From 40e8c92a638a6d6d98715dbe0c868f98ccf89284 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Fri, 13 Oct 2023 17:50:47 +0000 Subject: [PATCH] chore: Update gapic-generator-python to v1.11.7 PiperOrigin-RevId: 573230664 Source-Link: https://github.com/googleapis/googleapis/commit/93beed334607e70709cc60e6145be65fdc8ec386 Source-Link: https://github.com/googleapis/googleapis-gen/commit/f4a4edaa8057639fcf6adf9179872280d1a8f651 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiZjRhNGVkYWE4MDU3NjM5ZmNmNmFkZjkxNzk4NzIyODBkMWE4ZjY1MSJ9 --- owl-bot-staging/v1/.coveragerc | 13 + owl-bot-staging/v1/.flake8 | 33 + owl-bot-staging/v1/MANIFEST.in | 2 + owl-bot-staging/v1/README.rst | 49 + owl-bot-staging/v1/docs/_static/custom.css | 3 + owl-bot-staging/v1/docs/conf.py | 376 + owl-bot-staging/v1/docs/index.rst | 7 + .../v1/docs/vision_v1/image_annotator.rst | 6 + .../v1/docs/vision_v1/product_search.rst | 10 + .../v1/docs/vision_v1/services.rst | 7 + owl-bot-staging/v1/docs/vision_v1/types.rst | 6 + .../v1/google/cloud/vision/__init__.py | 199 + .../v1/google/cloud/vision/gapic_version.py | 16 + .../v1/google/cloud/vision/py.typed | 2 + .../v1/google/cloud/vision_v1/__init__.py | 200 + .../cloud/vision_v1/gapic_metadata.json | 392 + .../google/cloud/vision_v1/gapic_version.py | 16 + .../v1/google/cloud/vision_v1/py.typed | 2 + .../cloud/vision_v1/services/__init__.py | 15 + .../services/image_annotator/__init__.py | 22 + .../services/image_annotator/async_client.py | 668 + .../services/image_annotator/client.py | 853 ++ .../image_annotator/transports/__init__.py | 38 + .../image_annotator/transports/base.py | 226 + .../image_annotator/transports/grpc.py | 390 + .../transports/grpc_asyncio.py | 389 + .../image_annotator/transports/rest.py | 754 + .../services/product_search/__init__.py | 22 + .../services/product_search/async_client.py | 2615 ++++ .../services/product_search/client.py | 2714 ++++ .../services/product_search/pagers.py | 502 + .../product_search/transports/__init__.py | 38 + .../product_search/transports/base.py | 532 + .../product_search/transports/grpc.py | 924 ++ .../product_search/transports/grpc_asyncio.py | 923 ++ .../product_search/transports/rest.py | 2322 +++ .../google/cloud/vision_v1/types/__init__.py | 198 + .../google/cloud/vision_v1/types/geometry.py | 129 + .../cloud/vision_v1/types/image_annotator.py | 1725 +++ .../cloud/vision_v1/types/product_search.py | 227 + .../vision_v1/types/product_search_service.py | 1114 ++ .../cloud/vision_v1/types/text_annotation.py | 429 + .../cloud/vision_v1/types/web_detection.py | 205 + owl-bot-staging/v1/mypy.ini | 3 + owl-bot-staging/v1/noxfile.py | 184 + ...ippet_metadata_google.cloud.vision.v1.json | 3784 +++++ ...otator_async_batch_annotate_files_async.py | 55 + ...notator_async_batch_annotate_files_sync.py | 55 + ...tator_async_batch_annotate_images_async.py | 55 + ...otator_async_batch_annotate_images_sync.py | 55 + ...ge_annotator_batch_annotate_files_async.py | 51 + ...age_annotator_batch_annotate_files_sync.py | 51 + ...e_annotator_batch_annotate_images_async.py | 51 + ...ge_annotator_batch_annotate_images_sync.py | 51 + ...search_add_product_to_product_set_async.py | 51 + ..._search_add_product_to_product_set_sync.py | 51 + ...ted_product_search_create_product_async.py | 52 + ...product_search_create_product_set_async.py | 52 + ..._product_search_create_product_set_sync.py | 52 + ...ated_product_search_create_product_sync.py | 52 + ...uct_search_create_reference_image_async.py | 56 + ...duct_search_create_reference_image_sync.py | 56 + ...ted_product_search_delete_product_async.py | 50 + ...product_search_delete_product_set_async.py | 50 + ..._product_search_delete_product_set_sync.py | 50 + ...ated_product_search_delete_product_sync.py | 50 + ...uct_search_delete_reference_image_async.py | 50 + ...duct_search_delete_reference_image_sync.py | 50 + ...erated_product_search_get_product_async.py | 52 + ...ed_product_search_get_product_set_async.py | 52 + ...ted_product_search_get_product_set_sync.py | 52 + ...nerated_product_search_get_product_sync.py | 52 + ...roduct_search_get_reference_image_async.py | 52 + ...product_search_get_reference_image_sync.py | 52 + ...roduct_search_import_product_sets_async.py | 56 + ...product_search_import_product_sets_sync.py | 56 + ..._product_search_list_product_sets_async.py | 53 + ...d_product_search_list_product_sets_sync.py | 53 + ...ated_product_search_list_products_async.py | 53 + ...arch_list_products_in_product_set_async.py | 53 + ...earch_list_products_in_product_set_sync.py | 53 + ...rated_product_search_list_products_sync.py | 53 + ...duct_search_list_reference_images_async.py | 53 + ...oduct_search_list_reference_images_sync.py | 53 + ...ted_product_search_purge_products_async.py | 56 + ...ated_product_search_purge_products_sync.py | 56 + ...h_remove_product_from_product_set_async.py | 51 + ...ch_remove_product_from_product_set_sync.py | 51 + ...ted_product_search_update_product_async.py | 51 + ...product_search_update_product_set_async.py | 51 + ..._product_search_update_product_set_sync.py | 51 + ...ated_product_search_update_product_sync.py | 51 + .../v1/scripts/fixup_vision_v1_keywords.py | 198 + owl-bot-staging/v1/setup.py | 90 + .../v1/testing/constraints-3.10.txt | 6 + .../v1/testing/constraints-3.11.txt | 6 + .../v1/testing/constraints-3.12.txt | 6 + .../v1/testing/constraints-3.7.txt | 9 + .../v1/testing/constraints-3.8.txt | 6 + .../v1/testing/constraints-3.9.txt | 6 + owl-bot-staging/v1/tests/__init__.py | 16 + owl-bot-staging/v1/tests/unit/__init__.py | 16 + .../v1/tests/unit/gapic/__init__.py | 16 + .../v1/tests/unit/gapic/vision_v1/__init__.py | 16 + .../gapic/vision_v1/test_image_annotator.py | 2900 ++++ .../gapic/vision_v1/test_product_search.py | 11710 ++++++++++++++++ owl-bot-staging/v1p1beta1/.coveragerc | 13 + owl-bot-staging/v1p1beta1/.flake8 | 33 + owl-bot-staging/v1p1beta1/MANIFEST.in | 2 + owl-bot-staging/v1p1beta1/README.rst | 49 + .../v1p1beta1/docs/_static/custom.css | 3 + owl-bot-staging/v1p1beta1/docs/conf.py | 376 + owl-bot-staging/v1p1beta1/docs/index.rst | 7 + .../docs/vision_v1p1beta1/image_annotator.rst | 6 + .../docs/vision_v1p1beta1/services.rst | 6 + .../v1p1beta1/docs/vision_v1p1beta1/types.rst | 6 + .../v1p1beta1/google/cloud/vision/__init__.py | 93 + .../google/cloud/vision/gapic_version.py | 16 + .../v1p1beta1/google/cloud/vision/py.typed | 2 + .../google/cloud/vision_v1p1beta1/__init__.py | 94 + .../vision_v1p1beta1/gapic_metadata.json | 43 + .../cloud/vision_v1p1beta1/gapic_version.py | 16 + .../google/cloud/vision_v1p1beta1/py.typed | 2 + .../vision_v1p1beta1/services/__init__.py | 15 + .../services/image_annotator/__init__.py | 22 + .../services/image_annotator/async_client.py | 299 + .../services/image_annotator/client.py | 487 + .../image_annotator/transports/__init__.py | 38 + .../image_annotator/transports/base.py | 156 + .../image_annotator/transports/grpc.py | 268 + .../transports/grpc_asyncio.py | 267 + .../image_annotator/transports/rest.py | 303 + .../cloud/vision_v1p1beta1/types/__init__.py | 92 + .../cloud/vision_v1p1beta1/types/geometry.py | 99 + .../vision_v1p1beta1/types/image_annotator.py | 1080 ++ .../vision_v1p1beta1/types/text_annotation.py | 414 + .../vision_v1p1beta1/types/web_detection.py | 203 + owl-bot-staging/v1p1beta1/mypy.ini | 3 + owl-bot-staging/v1p1beta1/noxfile.py | 184 + ...etadata_google.cloud.vision.v1p1beta1.json | 176 + ...e_annotator_batch_annotate_images_async.py | 51 + ...ge_annotator_batch_annotate_images_sync.py | 51 + .../fixup_vision_v1p1beta1_keywords.py | 176 + owl-bot-staging/v1p1beta1/setup.py | 90 + .../v1p1beta1/testing/constraints-3.10.txt | 6 + .../v1p1beta1/testing/constraints-3.11.txt | 6 + .../v1p1beta1/testing/constraints-3.12.txt | 6 + .../v1p1beta1/testing/constraints-3.7.txt | 9 + .../v1p1beta1/testing/constraints-3.8.txt | 6 + .../v1p1beta1/testing/constraints-3.9.txt | 6 + owl-bot-staging/v1p1beta1/tests/__init__.py | 16 + .../v1p1beta1/tests/unit/__init__.py | 16 + .../v1p1beta1/tests/unit/gapic/__init__.py | 16 + .../unit/gapic/vision_v1p1beta1/__init__.py | 16 + .../vision_v1p1beta1/test_image_annotator.py | 1596 +++ owl-bot-staging/v1p2beta1/.coveragerc | 13 + owl-bot-staging/v1p2beta1/.flake8 | 33 + owl-bot-staging/v1p2beta1/MANIFEST.in | 2 + owl-bot-staging/v1p2beta1/README.rst | 49 + .../v1p2beta1/docs/_static/custom.css | 3 + owl-bot-staging/v1p2beta1/docs/conf.py | 376 + owl-bot-staging/v1p2beta1/docs/index.rst | 7 + .../docs/vision_v1p2beta1/image_annotator.rst | 6 + .../docs/vision_v1p2beta1/services.rst | 6 + .../v1p2beta1/docs/vision_v1p2beta1/types.rst | 6 + .../v1p2beta1/google/cloud/vision/__init__.py | 117 + .../google/cloud/vision/gapic_version.py | 16 + .../v1p2beta1/google/cloud/vision/py.typed | 2 + .../google/cloud/vision_v1p2beta1/__init__.py | 118 + .../vision_v1p2beta1/gapic_metadata.json | 58 + .../cloud/vision_v1p2beta1/gapic_version.py | 16 + .../google/cloud/vision_v1p2beta1/py.typed | 2 + .../vision_v1p2beta1/services/__init__.py | 15 + .../services/image_annotator/__init__.py | 22 + .../services/image_annotator/async_client.py | 422 + .../services/image_annotator/client.py | 603 + .../image_annotator/transports/__init__.py | 38 + .../image_annotator/transports/base.py | 184 + .../image_annotator/transports/grpc.py | 319 + .../transports/grpc_asyncio.py | 318 + .../image_annotator/transports/rest.py | 454 + .../cloud/vision_v1p2beta1/types/__init__.py | 116 + .../cloud/vision_v1p2beta1/types/geometry.py | 129 + .../vision_v1p2beta1/types/image_annotator.py | 1406 ++ .../vision_v1p2beta1/types/text_annotation.py | 429 + .../vision_v1p2beta1/types/web_detection.py | 203 + owl-bot-staging/v1p2beta1/mypy.ini | 3 + owl-bot-staging/v1p2beta1/noxfile.py | 184 + ...etadata_google.cloud.vision.v1p2beta1.json | 337 + ...otator_async_batch_annotate_files_async.py | 55 + ...notator_async_batch_annotate_files_sync.py | 55 + ...e_annotator_batch_annotate_images_async.py | 51 + ...ge_annotator_batch_annotate_images_sync.py | 51 + .../fixup_vision_v1p2beta1_keywords.py | 177 + owl-bot-staging/v1p2beta1/setup.py | 90 + .../v1p2beta1/testing/constraints-3.10.txt | 6 + .../v1p2beta1/testing/constraints-3.11.txt | 6 + .../v1p2beta1/testing/constraints-3.12.txt | 6 + .../v1p2beta1/testing/constraints-3.7.txt | 9 + .../v1p2beta1/testing/constraints-3.8.txt | 6 + .../v1p2beta1/testing/constraints-3.9.txt | 6 + owl-bot-staging/v1p2beta1/tests/__init__.py | 16 + .../v1p2beta1/tests/unit/__init__.py | 16 + .../v1p2beta1/tests/unit/gapic/__init__.py | 16 + .../unit/gapic/vision_v1p2beta1/__init__.py | 16 + .../vision_v1p2beta1/test_image_annotator.py | 2051 +++ owl-bot-staging/v1p3beta1/.coveragerc | 13 + owl-bot-staging/v1p3beta1/.flake8 | 33 + owl-bot-staging/v1p3beta1/MANIFEST.in | 2 + owl-bot-staging/v1p3beta1/README.rst | 49 + .../v1p3beta1/docs/_static/custom.css | 3 + owl-bot-staging/v1p3beta1/docs/conf.py | 376 + owl-bot-staging/v1p3beta1/docs/index.rst | 7 + .../docs/vision_v1p3beta1/image_annotator.rst | 6 + .../docs/vision_v1p3beta1/product_search.rst | 10 + .../docs/vision_v1p3beta1/services.rst | 7 + .../v1p3beta1/docs/vision_v1p3beta1/types.rst | 6 + .../v1p3beta1/google/cloud/vision/__init__.py | 185 + .../google/cloud/vision/gapic_version.py | 16 + .../v1p3beta1/google/cloud/vision/py.typed | 2 + .../google/cloud/vision_v1p3beta1/__init__.py | 186 + .../vision_v1p3beta1/gapic_metadata.json | 347 + .../cloud/vision_v1p3beta1/gapic_version.py | 16 + .../google/cloud/vision_v1p3beta1/py.typed | 2 + .../vision_v1p3beta1/services/__init__.py | 15 + .../services/image_annotator/__init__.py | 22 + .../services/image_annotator/async_client.py | 424 + .../services/image_annotator/client.py | 625 + .../image_annotator/transports/__init__.py | 38 + .../image_annotator/transports/base.py | 182 + .../image_annotator/transports/grpc.py | 319 + .../transports/grpc_asyncio.py | 318 + .../image_annotator/transports/rest.py | 454 + .../services/product_search/__init__.py | 22 + .../services/product_search/async_client.py | 2471 ++++ .../services/product_search/client.py | 2583 ++++ .../services/product_search/pagers.py | 502 + .../product_search/transports/__init__.py | 38 + .../product_search/transports/base.py | 505 + .../product_search/transports/grpc.py | 890 ++ .../product_search/transports/grpc_asyncio.py | 889 ++ .../product_search/transports/rest.py | 2186 +++ .../cloud/vision_v1p3beta1/types/__init__.py | 184 + .../cloud/vision_v1p3beta1/types/geometry.py | 129 + .../vision_v1p3beta1/types/image_annotator.py | 1481 ++ .../vision_v1p3beta1/types/product_search.py | 227 + .../types/product_search_service.py | 1026 ++ .../vision_v1p3beta1/types/text_annotation.py | 429 + .../vision_v1p3beta1/types/web_detection.py | 203 + owl-bot-staging/v1p3beta1/mypy.ini | 3 + owl-bot-staging/v1p3beta1/noxfile.py | 184 + ...etadata_google.cloud.vision.v1p3beta1.json | 3293 +++++ ...otator_async_batch_annotate_files_async.py | 55 + ...notator_async_batch_annotate_files_sync.py | 55 + ...e_annotator_batch_annotate_images_async.py | 51 + ...ge_annotator_batch_annotate_images_sync.py | 51 + ...search_add_product_to_product_set_async.py | 51 + ..._search_add_product_to_product_set_sync.py | 51 + ...ted_product_search_create_product_async.py | 52 + ...product_search_create_product_set_async.py | 52 + ..._product_search_create_product_set_sync.py | 52 + ...ated_product_search_create_product_sync.py | 52 + ...uct_search_create_reference_image_async.py | 56 + ...duct_search_create_reference_image_sync.py | 56 + ...ted_product_search_delete_product_async.py | 50 + ...product_search_delete_product_set_async.py | 50 + ..._product_search_delete_product_set_sync.py | 50 + ...ated_product_search_delete_product_sync.py | 50 + ...uct_search_delete_reference_image_async.py | 50 + ...duct_search_delete_reference_image_sync.py | 50 + ...erated_product_search_get_product_async.py | 52 + ...ed_product_search_get_product_set_async.py | 52 + ...ted_product_search_get_product_set_sync.py | 52 + ...nerated_product_search_get_product_sync.py | 52 + ...roduct_search_get_reference_image_async.py | 52 + ...product_search_get_reference_image_sync.py | 52 + ...roduct_search_import_product_sets_async.py | 56 + ...product_search_import_product_sets_sync.py | 56 + ..._product_search_list_product_sets_async.py | 53 + ...d_product_search_list_product_sets_sync.py | 53 + ...ated_product_search_list_products_async.py | 53 + ...arch_list_products_in_product_set_async.py | 53 + ...earch_list_products_in_product_set_sync.py | 53 + ...rated_product_search_list_products_sync.py | 53 + ...duct_search_list_reference_images_async.py | 53 + ...oduct_search_list_reference_images_sync.py | 53 + ...h_remove_product_from_product_set_async.py | 51 + ...ch_remove_product_from_product_set_sync.py | 51 + ...ted_product_search_update_product_async.py | 51 + ...product_search_update_product_set_async.py | 51 + ..._product_search_update_product_set_sync.py | 51 + ...ated_product_search_update_product_sync.py | 51 + .../fixup_vision_v1p3beta1_keywords.py | 195 + owl-bot-staging/v1p3beta1/setup.py | 90 + .../v1p3beta1/testing/constraints-3.10.txt | 6 + .../v1p3beta1/testing/constraints-3.11.txt | 6 + .../v1p3beta1/testing/constraints-3.12.txt | 6 + .../v1p3beta1/testing/constraints-3.7.txt | 9 + .../v1p3beta1/testing/constraints-3.8.txt | 6 + .../v1p3beta1/testing/constraints-3.9.txt | 6 + owl-bot-staging/v1p3beta1/tests/__init__.py | 16 + .../v1p3beta1/tests/unit/__init__.py | 16 + .../v1p3beta1/tests/unit/gapic/__init__.py | 16 + .../unit/gapic/vision_v1p3beta1/__init__.py | 16 + .../vision_v1p3beta1/test_image_annotator.py | 2095 +++ .../vision_v1p3beta1/test_product_search.py | 11247 +++++++++++++++ owl-bot-staging/v1p4beta1/.coveragerc | 13 + owl-bot-staging/v1p4beta1/.flake8 | 33 + owl-bot-staging/v1p4beta1/MANIFEST.in | 2 + owl-bot-staging/v1p4beta1/README.rst | 49 + .../v1p4beta1/docs/_static/custom.css | 3 + owl-bot-staging/v1p4beta1/docs/conf.py | 376 + owl-bot-staging/v1p4beta1/docs/index.rst | 7 + .../docs/vision_v1p4beta1/image_annotator.rst | 6 + .../docs/vision_v1p4beta1/product_search.rst | 10 + .../docs/vision_v1p4beta1/services.rst | 7 + .../v1p4beta1/docs/vision_v1p4beta1/types.rst | 6 + .../v1p4beta1/google/cloud/vision/__init__.py | 205 + .../google/cloud/vision/gapic_version.py | 16 + .../v1p4beta1/google/cloud/vision/py.typed | 2 + .../google/cloud/vision_v1p4beta1/__init__.py | 206 + .../vision_v1p4beta1/gapic_metadata.json | 392 + .../cloud/vision_v1p4beta1/gapic_version.py | 16 + .../google/cloud/vision_v1p4beta1/py.typed | 2 + .../vision_v1p4beta1/services/__init__.py | 15 + .../services/image_annotator/__init__.py | 22 + .../services/image_annotator/async_client.py | 660 + .../services/image_annotator/client.py | 853 ++ .../image_annotator/transports/__init__.py | 38 + .../image_annotator/transports/base.py | 218 + .../image_annotator/transports/grpc.py | 390 + .../transports/grpc_asyncio.py | 389 + .../image_annotator/transports/rest.py | 696 + .../services/product_search/__init__.py | 22 + .../services/product_search/async_client.py | 2606 ++++ .../services/product_search/client.py | 2718 ++++ .../services/product_search/pagers.py | 502 + .../product_search/transports/__init__.py | 38 + .../product_search/transports/base.py | 519 + .../product_search/transports/grpc.py | 926 ++ .../product_search/transports/grpc_asyncio.py | 925 ++ .../product_search/transports/rest.py | 2306 +++ .../cloud/vision_v1p4beta1/types/__init__.py | 206 + .../cloud/vision_v1p4beta1/types/face.py | 101 + .../cloud/vision_v1p4beta1/types/geometry.py | 129 + .../vision_v1p4beta1/types/image_annotator.py | 1669 +++ .../vision_v1p4beta1/types/product_search.py | 227 + .../types/product_search_service.py | 1116 ++ .../vision_v1p4beta1/types/text_annotation.py | 429 + .../vision_v1p4beta1/types/web_detection.py | 205 + owl-bot-staging/v1p4beta1/mypy.ini | 3 + owl-bot-staging/v1p4beta1/noxfile.py | 184 + ...etadata_google.cloud.vision.v1p4beta1.json | 3784 +++++ ...otator_async_batch_annotate_files_async.py | 55 + ...notator_async_batch_annotate_files_sync.py | 55 + ...tator_async_batch_annotate_images_async.py | 55 + ...otator_async_batch_annotate_images_sync.py | 55 + ...ge_annotator_batch_annotate_files_async.py | 51 + ...age_annotator_batch_annotate_files_sync.py | 51 + ...e_annotator_batch_annotate_images_async.py | 51 + ...ge_annotator_batch_annotate_images_sync.py | 51 + ...search_add_product_to_product_set_async.py | 51 + ..._search_add_product_to_product_set_sync.py | 51 + ...ted_product_search_create_product_async.py | 52 + ...product_search_create_product_set_async.py | 52 + ..._product_search_create_product_set_sync.py | 52 + ...ated_product_search_create_product_sync.py | 52 + ...uct_search_create_reference_image_async.py | 56 + ...duct_search_create_reference_image_sync.py | 56 + ...ted_product_search_delete_product_async.py | 50 + ...product_search_delete_product_set_async.py | 50 + ..._product_search_delete_product_set_sync.py | 50 + ...ated_product_search_delete_product_sync.py | 50 + ...uct_search_delete_reference_image_async.py | 50 + ...duct_search_delete_reference_image_sync.py | 50 + ...erated_product_search_get_product_async.py | 52 + ...ed_product_search_get_product_set_async.py | 52 + ...ted_product_search_get_product_set_sync.py | 52 + ...nerated_product_search_get_product_sync.py | 52 + ...roduct_search_get_reference_image_async.py | 52 + ...product_search_get_reference_image_sync.py | 52 + ...roduct_search_import_product_sets_async.py | 56 + ...product_search_import_product_sets_sync.py | 56 + ..._product_search_list_product_sets_async.py | 53 + ...d_product_search_list_product_sets_sync.py | 53 + ...ated_product_search_list_products_async.py | 53 + ...arch_list_products_in_product_set_async.py | 53 + ...earch_list_products_in_product_set_sync.py | 53 + ...rated_product_search_list_products_sync.py | 53 + ...duct_search_list_reference_images_async.py | 53 + ...oduct_search_list_reference_images_sync.py | 53 + ...ted_product_search_purge_products_async.py | 56 + ...ated_product_search_purge_products_sync.py | 56 + ...h_remove_product_from_product_set_async.py | 51 + ...ch_remove_product_from_product_set_sync.py | 51 + ...ted_product_search_update_product_async.py | 51 + ...product_search_update_product_set_async.py | 51 + ..._product_search_update_product_set_sync.py | 51 + ...ated_product_search_update_product_sync.py | 51 + .../fixup_vision_v1p4beta1_keywords.py | 198 + owl-bot-staging/v1p4beta1/setup.py | 90 + .../v1p4beta1/testing/constraints-3.10.txt | 6 + .../v1p4beta1/testing/constraints-3.11.txt | 6 + .../v1p4beta1/testing/constraints-3.12.txt | 6 + .../v1p4beta1/testing/constraints-3.7.txt | 9 + .../v1p4beta1/testing/constraints-3.8.txt | 6 + .../v1p4beta1/testing/constraints-3.9.txt | 6 + owl-bot-staging/v1p4beta1/tests/__init__.py | 16 + .../v1p4beta1/tests/unit/__init__.py | 16 + .../v1p4beta1/tests/unit/gapic/__init__.py | 16 + .../unit/gapic/vision_v1p4beta1/__init__.py | 16 + .../vision_v1p4beta1/test_image_annotator.py | 2901 ++++ .../vision_v1p4beta1/test_product_search.py | 11710 ++++++++++++++++ 413 files changed, 133669 insertions(+) create mode 100644 owl-bot-staging/v1/.coveragerc create mode 100644 owl-bot-staging/v1/.flake8 create mode 100644 owl-bot-staging/v1/MANIFEST.in create mode 100644 owl-bot-staging/v1/README.rst create mode 100644 owl-bot-staging/v1/docs/_static/custom.css create mode 100644 owl-bot-staging/v1/docs/conf.py create mode 100644 owl-bot-staging/v1/docs/index.rst create mode 100644 owl-bot-staging/v1/docs/vision_v1/image_annotator.rst create mode 100644 owl-bot-staging/v1/docs/vision_v1/product_search.rst create mode 100644 owl-bot-staging/v1/docs/vision_v1/services.rst create mode 100644 owl-bot-staging/v1/docs/vision_v1/types.rst create mode 100644 owl-bot-staging/v1/google/cloud/vision/__init__.py create mode 100644 owl-bot-staging/v1/google/cloud/vision/gapic_version.py create mode 100644 owl-bot-staging/v1/google/cloud/vision/py.typed create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/__init__.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/gapic_metadata.json create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/gapic_version.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/py.typed create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/__init__.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/__init__.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/async_client.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/client.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/__init__.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/base.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/grpc.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/rest.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/__init__.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/async_client.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/client.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/pagers.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/__init__.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/base.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/grpc.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/rest.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/types/__init__.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/types/geometry.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/types/image_annotator.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/types/product_search.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/types/product_search_service.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/types/text_annotation.py create mode 100644 owl-bot-staging/v1/google/cloud/vision_v1/types/web_detection.py create mode 100644 owl-bot-staging/v1/mypy.ini create mode 100644 owl-bot-staging/v1/noxfile.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_files_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_files_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_images_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_images_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_files_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_files_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_images_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_images_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_add_product_to_product_set_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_add_product_to_product_set_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_set_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_set_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_reference_image_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_reference_image_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_set_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_set_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_reference_image_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_reference_image_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_set_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_set_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_reference_image_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_reference_image_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_import_product_sets_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_import_product_sets_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_product_sets_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_product_sets_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_in_product_set_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_in_product_set_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_reference_images_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_reference_images_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_purge_products_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_purge_products_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_remove_product_from_product_set_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_remove_product_from_product_set_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_set_async.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_set_sync.py create mode 100644 owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_sync.py create mode 100644 owl-bot-staging/v1/scripts/fixup_vision_v1_keywords.py create mode 100644 owl-bot-staging/v1/setup.py create mode 100644 owl-bot-staging/v1/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/v1/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/v1/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/v1/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/v1/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/v1/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/v1/tests/__init__.py create mode 100644 owl-bot-staging/v1/tests/unit/__init__.py create mode 100644 owl-bot-staging/v1/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v1/tests/unit/gapic/vision_v1/__init__.py create mode 100644 owl-bot-staging/v1/tests/unit/gapic/vision_v1/test_image_annotator.py create mode 100644 owl-bot-staging/v1/tests/unit/gapic/vision_v1/test_product_search.py create mode 100644 owl-bot-staging/v1p1beta1/.coveragerc create mode 100644 owl-bot-staging/v1p1beta1/.flake8 create mode 100644 owl-bot-staging/v1p1beta1/MANIFEST.in create mode 100644 owl-bot-staging/v1p1beta1/README.rst create mode 100644 owl-bot-staging/v1p1beta1/docs/_static/custom.css create mode 100644 owl-bot-staging/v1p1beta1/docs/conf.py create mode 100644 owl-bot-staging/v1p1beta1/docs/index.rst create mode 100644 owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/image_annotator.rst create mode 100644 owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/services.rst create mode 100644 owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/types.rst create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision/gapic_version.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision/py.typed create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/gapic_metadata.json create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/gapic_version.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/py.typed create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/async_client.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/client.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/base.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/grpc.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/rest.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/geometry.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/image_annotator.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/text_annotation.py create mode 100644 owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/web_detection.py create mode 100644 owl-bot-staging/v1p1beta1/mypy.ini create mode 100644 owl-bot-staging/v1p1beta1/noxfile.py create mode 100644 owl-bot-staging/v1p1beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json create mode 100644 owl-bot-staging/v1p1beta1/samples/generated_samples/vision_v1p1beta1_generated_image_annotator_batch_annotate_images_async.py create mode 100644 owl-bot-staging/v1p1beta1/samples/generated_samples/vision_v1p1beta1_generated_image_annotator_batch_annotate_images_sync.py create mode 100644 owl-bot-staging/v1p1beta1/scripts/fixup_vision_v1p1beta1_keywords.py create mode 100644 owl-bot-staging/v1p1beta1/setup.py create mode 100644 owl-bot-staging/v1p1beta1/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/v1p1beta1/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/v1p1beta1/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/v1p1beta1/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/v1p1beta1/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/v1p1beta1/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/v1p1beta1/tests/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/tests/unit/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/tests/unit/gapic/vision_v1p1beta1/__init__.py create mode 100644 owl-bot-staging/v1p1beta1/tests/unit/gapic/vision_v1p1beta1/test_image_annotator.py create mode 100644 owl-bot-staging/v1p2beta1/.coveragerc create mode 100644 owl-bot-staging/v1p2beta1/.flake8 create mode 100644 owl-bot-staging/v1p2beta1/MANIFEST.in create mode 100644 owl-bot-staging/v1p2beta1/README.rst create mode 100644 owl-bot-staging/v1p2beta1/docs/_static/custom.css create mode 100644 owl-bot-staging/v1p2beta1/docs/conf.py create mode 100644 owl-bot-staging/v1p2beta1/docs/index.rst create mode 100644 owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/image_annotator.rst create mode 100644 owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/services.rst create mode 100644 owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/types.rst create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision/gapic_version.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision/py.typed create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/gapic_metadata.json create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/gapic_version.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/py.typed create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/async_client.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/client.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/base.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/grpc.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/rest.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/geometry.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/image_annotator.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/text_annotation.py create mode 100644 owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/web_detection.py create mode 100644 owl-bot-staging/v1p2beta1/mypy.ini create mode 100644 owl-bot-staging/v1p2beta1/noxfile.py create mode 100644 owl-bot-staging/v1p2beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json create mode 100644 owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_async.py create mode 100644 owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_sync.py create mode 100644 owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_batch_annotate_images_async.py create mode 100644 owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_batch_annotate_images_sync.py create mode 100644 owl-bot-staging/v1p2beta1/scripts/fixup_vision_v1p2beta1_keywords.py create mode 100644 owl-bot-staging/v1p2beta1/setup.py create mode 100644 owl-bot-staging/v1p2beta1/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/v1p2beta1/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/v1p2beta1/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/v1p2beta1/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/v1p2beta1/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/v1p2beta1/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/v1p2beta1/tests/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/tests/unit/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/tests/unit/gapic/vision_v1p2beta1/__init__.py create mode 100644 owl-bot-staging/v1p2beta1/tests/unit/gapic/vision_v1p2beta1/test_image_annotator.py create mode 100644 owl-bot-staging/v1p3beta1/.coveragerc create mode 100644 owl-bot-staging/v1p3beta1/.flake8 create mode 100644 owl-bot-staging/v1p3beta1/MANIFEST.in create mode 100644 owl-bot-staging/v1p3beta1/README.rst create mode 100644 owl-bot-staging/v1p3beta1/docs/_static/custom.css create mode 100644 owl-bot-staging/v1p3beta1/docs/conf.py create mode 100644 owl-bot-staging/v1p3beta1/docs/index.rst create mode 100644 owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/image_annotator.rst create mode 100644 owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/product_search.rst create mode 100644 owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/services.rst create mode 100644 owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/types.rst create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision/gapic_version.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision/py.typed create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/gapic_metadata.json create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/gapic_version.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/py.typed create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/async_client.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/client.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/base.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/grpc.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/rest.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/async_client.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/client.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/pagers.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/base.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/grpc.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/rest.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/geometry.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/image_annotator.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/product_search.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/product_search_service.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/text_annotation.py create mode 100644 owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/web_detection.py create mode 100644 owl-bot-staging/v1p3beta1/mypy.ini create mode 100644 owl-bot-staging/v1p3beta1/noxfile.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_batch_annotate_images_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_batch_annotate_images_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_add_product_to_product_set_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_add_product_to_product_set_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_set_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_set_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_reference_image_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_reference_image_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_set_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_set_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_reference_image_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_reference_image_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_set_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_set_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_reference_image_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_reference_image_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_import_product_sets_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_import_product_sets_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_product_sets_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_product_sets_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_in_product_set_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_in_product_set_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_reference_images_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_reference_images_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_remove_product_from_product_set_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_remove_product_from_product_set_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_set_async.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_set_sync.py create mode 100644 owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_sync.py create mode 100644 owl-bot-staging/v1p3beta1/scripts/fixup_vision_v1p3beta1_keywords.py create mode 100644 owl-bot-staging/v1p3beta1/setup.py create mode 100644 owl-bot-staging/v1p3beta1/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/v1p3beta1/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/v1p3beta1/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/v1p3beta1/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/v1p3beta1/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/v1p3beta1/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/v1p3beta1/tests/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/tests/unit/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/__init__.py create mode 100644 owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/test_image_annotator.py create mode 100644 owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/test_product_search.py create mode 100644 owl-bot-staging/v1p4beta1/.coveragerc create mode 100644 owl-bot-staging/v1p4beta1/.flake8 create mode 100644 owl-bot-staging/v1p4beta1/MANIFEST.in create mode 100644 owl-bot-staging/v1p4beta1/README.rst create mode 100644 owl-bot-staging/v1p4beta1/docs/_static/custom.css create mode 100644 owl-bot-staging/v1p4beta1/docs/conf.py create mode 100644 owl-bot-staging/v1p4beta1/docs/index.rst create mode 100644 owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/image_annotator.rst create mode 100644 owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/product_search.rst create mode 100644 owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/services.rst create mode 100644 owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/types.rst create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision/gapic_version.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision/py.typed create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/gapic_metadata.json create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/gapic_version.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/py.typed create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/async_client.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/client.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/base.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/grpc.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/rest.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/async_client.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/client.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/pagers.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/base.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/grpc.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/rest.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/face.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/geometry.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/image_annotator.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/product_search.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/product_search_service.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/text_annotation.py create mode 100644 owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/web_detection.py create mode 100644 owl-bot-staging/v1p4beta1/mypy.ini create mode 100644 owl-bot-staging/v1p4beta1/noxfile.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_files_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_files_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_images_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_images_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_add_product_to_product_set_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_add_product_to_product_set_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_set_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_set_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_reference_image_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_reference_image_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_set_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_set_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_reference_image_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_reference_image_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_set_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_set_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_reference_image_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_reference_image_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_import_product_sets_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_import_product_sets_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_product_sets_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_product_sets_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_in_product_set_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_in_product_set_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_reference_images_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_reference_images_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_purge_products_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_purge_products_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_remove_product_from_product_set_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_remove_product_from_product_set_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_set_async.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_set_sync.py create mode 100644 owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_sync.py create mode 100644 owl-bot-staging/v1p4beta1/scripts/fixup_vision_v1p4beta1_keywords.py create mode 100644 owl-bot-staging/v1p4beta1/setup.py create mode 100644 owl-bot-staging/v1p4beta1/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/v1p4beta1/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/v1p4beta1/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/v1p4beta1/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/v1p4beta1/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/v1p4beta1/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/v1p4beta1/tests/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/tests/unit/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/__init__.py create mode 100644 owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/test_image_annotator.py create mode 100644 owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/test_product_search.py diff --git a/owl-bot-staging/v1/.coveragerc b/owl-bot-staging/v1/.coveragerc new file mode 100644 index 00000000..cbf0b85a --- /dev/null +++ b/owl-bot-staging/v1/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/vision/__init__.py + google/cloud/vision/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/owl-bot-staging/v1/.flake8 b/owl-bot-staging/v1/.flake8 new file mode 100644 index 00000000..29227d4c --- /dev/null +++ b/owl-bot-staging/v1/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2020 Google LLC +# +# Licensed 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 +# +# https://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. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/owl-bot-staging/v1/MANIFEST.in b/owl-bot-staging/v1/MANIFEST.in new file mode 100644 index 00000000..67aa21f9 --- /dev/null +++ b/owl-bot-staging/v1/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/vision *.py +recursive-include google/cloud/vision_v1 *.py diff --git a/owl-bot-staging/v1/README.rst b/owl-bot-staging/v1/README.rst new file mode 100644 index 00000000..39f9ca72 --- /dev/null +++ b/owl-bot-staging/v1/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Vision API +================================================= + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. Enable the Google Cloud Vision API. +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a `virtualenv`_ using pip. `virtualenv`_ is a tool to +create isolated Python environments. The basic problem it addresses is one of +dependencies and versions, and indirectly permissions. + +With `virtualenv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ + + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + /bin/pip install /path/to/library + + +Windows +^^^^^^^ + +.. code-block:: console + + python3 -m venv + \Scripts\activate + \Scripts\pip.exe install \path\to\library diff --git a/owl-bot-staging/v1/docs/_static/custom.css b/owl-bot-staging/v1/docs/_static/custom.css new file mode 100644 index 00000000..06423be0 --- /dev/null +++ b/owl-bot-staging/v1/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/v1/docs/conf.py b/owl-bot-staging/v1/docs/conf.py new file mode 100644 index 00000000..c75f569a --- /dev/null +++ b/owl-bot-staging/v1/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# +# google-cloud-vision documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import shlex + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +__version__ = "0.1.0" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.0.1" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_flags = ["members"] +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# Allow markdown includes (so releases.md can include CHANGLEOG.md) +# http://www.sphinx-doc.org/en/master/markdown.html +source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = u"google-cloud-vision" +copyright = u"2023, Google, LLC" +author = u"Google APIs" # TODO: autogenerate this bit + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for Python", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-cloud-vision-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', + # Latex figure (float) alignment + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + root_doc, + "google-cloud-vision.tex", + u"google-cloud-vision Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + root_doc, + "google-cloud-vision", + u"Google Cloud Vision Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + root_doc, + "google-cloud-vision", + u"google-cloud-vision Documentation", + author, + "google-cloud-vision", + "GAPIC library for Google Cloud Vision API", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("http://python.readthedocs.org/en/latest/", None), + "gax": ("https://gax-python.readthedocs.org/en/latest/", None), + "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), + "google-gax": ("https://gax-python.readthedocs.io/en/latest/", None), + "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None), + "grpc": ("https://grpc.io/grpc/python/", None), + "requests": ("http://requests.kennethreitz.org/en/stable/", None), + "proto": ("https://proto-plus-python.readthedocs.io/en/stable", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/owl-bot-staging/v1/docs/index.rst b/owl-bot-staging/v1/docs/index.rst new file mode 100644 index 00000000..84760df1 --- /dev/null +++ b/owl-bot-staging/v1/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + vision_v1/services + vision_v1/types diff --git a/owl-bot-staging/v1/docs/vision_v1/image_annotator.rst b/owl-bot-staging/v1/docs/vision_v1/image_annotator.rst new file mode 100644 index 00000000..83130a76 --- /dev/null +++ b/owl-bot-staging/v1/docs/vision_v1/image_annotator.rst @@ -0,0 +1,6 @@ +ImageAnnotator +-------------------------------- + +.. automodule:: google.cloud.vision_v1.services.image_annotator + :members: + :inherited-members: diff --git a/owl-bot-staging/v1/docs/vision_v1/product_search.rst b/owl-bot-staging/v1/docs/vision_v1/product_search.rst new file mode 100644 index 00000000..96f1c798 --- /dev/null +++ b/owl-bot-staging/v1/docs/vision_v1/product_search.rst @@ -0,0 +1,10 @@ +ProductSearch +------------------------------- + +.. automodule:: google.cloud.vision_v1.services.product_search + :members: + :inherited-members: + +.. automodule:: google.cloud.vision_v1.services.product_search.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v1/docs/vision_v1/services.rst b/owl-bot-staging/v1/docs/vision_v1/services.rst new file mode 100644 index 00000000..5fe11bc5 --- /dev/null +++ b/owl-bot-staging/v1/docs/vision_v1/services.rst @@ -0,0 +1,7 @@ +Services for Google Cloud Vision v1 API +======================================= +.. toctree:: + :maxdepth: 2 + + image_annotator + product_search diff --git a/owl-bot-staging/v1/docs/vision_v1/types.rst b/owl-bot-staging/v1/docs/vision_v1/types.rst new file mode 100644 index 00000000..dbbb594c --- /dev/null +++ b/owl-bot-staging/v1/docs/vision_v1/types.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Vision v1 API +==================================== + +.. automodule:: google.cloud.vision_v1.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/v1/google/cloud/vision/__init__.py b/owl-bot-staging/v1/google/cloud/vision/__init__.py new file mode 100644 index 00000000..6937909e --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision/__init__.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.vision_v1.services.image_annotator.client import ImageAnnotatorClient +from google.cloud.vision_v1.services.image_annotator.async_client import ImageAnnotatorAsyncClient +from google.cloud.vision_v1.services.product_search.client import ProductSearchClient +from google.cloud.vision_v1.services.product_search.async_client import ProductSearchAsyncClient + +from google.cloud.vision_v1.types.geometry import BoundingPoly +from google.cloud.vision_v1.types.geometry import NormalizedVertex +from google.cloud.vision_v1.types.geometry import Position +from google.cloud.vision_v1.types.geometry import Vertex +from google.cloud.vision_v1.types.image_annotator import AnnotateFileRequest +from google.cloud.vision_v1.types.image_annotator import AnnotateFileResponse +from google.cloud.vision_v1.types.image_annotator import AnnotateImageRequest +from google.cloud.vision_v1.types.image_annotator import AnnotateImageResponse +from google.cloud.vision_v1.types.image_annotator import AsyncAnnotateFileRequest +from google.cloud.vision_v1.types.image_annotator import AsyncAnnotateFileResponse +from google.cloud.vision_v1.types.image_annotator import AsyncBatchAnnotateFilesRequest +from google.cloud.vision_v1.types.image_annotator import AsyncBatchAnnotateFilesResponse +from google.cloud.vision_v1.types.image_annotator import AsyncBatchAnnotateImagesRequest +from google.cloud.vision_v1.types.image_annotator import AsyncBatchAnnotateImagesResponse +from google.cloud.vision_v1.types.image_annotator import BatchAnnotateFilesRequest +from google.cloud.vision_v1.types.image_annotator import BatchAnnotateFilesResponse +from google.cloud.vision_v1.types.image_annotator import BatchAnnotateImagesRequest +from google.cloud.vision_v1.types.image_annotator import BatchAnnotateImagesResponse +from google.cloud.vision_v1.types.image_annotator import ColorInfo +from google.cloud.vision_v1.types.image_annotator import CropHint +from google.cloud.vision_v1.types.image_annotator import CropHintsAnnotation +from google.cloud.vision_v1.types.image_annotator import CropHintsParams +from google.cloud.vision_v1.types.image_annotator import DominantColorsAnnotation +from google.cloud.vision_v1.types.image_annotator import EntityAnnotation +from google.cloud.vision_v1.types.image_annotator import FaceAnnotation +from google.cloud.vision_v1.types.image_annotator import Feature +from google.cloud.vision_v1.types.image_annotator import GcsDestination +from google.cloud.vision_v1.types.image_annotator import GcsSource +from google.cloud.vision_v1.types.image_annotator import Image +from google.cloud.vision_v1.types.image_annotator import ImageAnnotationContext +from google.cloud.vision_v1.types.image_annotator import ImageContext +from google.cloud.vision_v1.types.image_annotator import ImageProperties +from google.cloud.vision_v1.types.image_annotator import ImageSource +from google.cloud.vision_v1.types.image_annotator import InputConfig +from google.cloud.vision_v1.types.image_annotator import LatLongRect +from google.cloud.vision_v1.types.image_annotator import LocalizedObjectAnnotation +from google.cloud.vision_v1.types.image_annotator import LocationInfo +from google.cloud.vision_v1.types.image_annotator import OperationMetadata +from google.cloud.vision_v1.types.image_annotator import OutputConfig +from google.cloud.vision_v1.types.image_annotator import Property +from google.cloud.vision_v1.types.image_annotator import SafeSearchAnnotation +from google.cloud.vision_v1.types.image_annotator import TextDetectionParams +from google.cloud.vision_v1.types.image_annotator import WebDetectionParams +from google.cloud.vision_v1.types.image_annotator import Likelihood +from google.cloud.vision_v1.types.product_search import ProductSearchParams +from google.cloud.vision_v1.types.product_search import ProductSearchResults +from google.cloud.vision_v1.types.product_search_service import AddProductToProductSetRequest +from google.cloud.vision_v1.types.product_search_service import BatchOperationMetadata +from google.cloud.vision_v1.types.product_search_service import CreateProductRequest +from google.cloud.vision_v1.types.product_search_service import CreateProductSetRequest +from google.cloud.vision_v1.types.product_search_service import CreateReferenceImageRequest +from google.cloud.vision_v1.types.product_search_service import DeleteProductRequest +from google.cloud.vision_v1.types.product_search_service import DeleteProductSetRequest +from google.cloud.vision_v1.types.product_search_service import DeleteReferenceImageRequest +from google.cloud.vision_v1.types.product_search_service import GetProductRequest +from google.cloud.vision_v1.types.product_search_service import GetProductSetRequest +from google.cloud.vision_v1.types.product_search_service import GetReferenceImageRequest +from google.cloud.vision_v1.types.product_search_service import ImportProductSetsGcsSource +from google.cloud.vision_v1.types.product_search_service import ImportProductSetsInputConfig +from google.cloud.vision_v1.types.product_search_service import ImportProductSetsRequest +from google.cloud.vision_v1.types.product_search_service import ImportProductSetsResponse +from google.cloud.vision_v1.types.product_search_service import ListProductSetsRequest +from google.cloud.vision_v1.types.product_search_service import ListProductSetsResponse +from google.cloud.vision_v1.types.product_search_service import ListProductsInProductSetRequest +from google.cloud.vision_v1.types.product_search_service import ListProductsInProductSetResponse +from google.cloud.vision_v1.types.product_search_service import ListProductsRequest +from google.cloud.vision_v1.types.product_search_service import ListProductsResponse +from google.cloud.vision_v1.types.product_search_service import ListReferenceImagesRequest +from google.cloud.vision_v1.types.product_search_service import ListReferenceImagesResponse +from google.cloud.vision_v1.types.product_search_service import Product +from google.cloud.vision_v1.types.product_search_service import ProductSet +from google.cloud.vision_v1.types.product_search_service import ProductSetPurgeConfig +from google.cloud.vision_v1.types.product_search_service import PurgeProductsRequest +from google.cloud.vision_v1.types.product_search_service import ReferenceImage +from google.cloud.vision_v1.types.product_search_service import RemoveProductFromProductSetRequest +from google.cloud.vision_v1.types.product_search_service import UpdateProductRequest +from google.cloud.vision_v1.types.product_search_service import UpdateProductSetRequest +from google.cloud.vision_v1.types.text_annotation import Block +from google.cloud.vision_v1.types.text_annotation import Page +from google.cloud.vision_v1.types.text_annotation import Paragraph +from google.cloud.vision_v1.types.text_annotation import Symbol +from google.cloud.vision_v1.types.text_annotation import TextAnnotation +from google.cloud.vision_v1.types.text_annotation import Word +from google.cloud.vision_v1.types.web_detection import WebDetection + +__all__ = ('ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', + 'ProductSearchClient', + 'ProductSearchAsyncClient', + 'BoundingPoly', + 'NormalizedVertex', + 'Position', + 'Vertex', + 'AnnotateFileRequest', + 'AnnotateFileResponse', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'AsyncBatchAnnotateImagesRequest', + 'AsyncBatchAnnotateImagesResponse', + 'BatchAnnotateFilesRequest', + 'BatchAnnotateFilesResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'GcsDestination', + 'GcsSource', + 'Image', + 'ImageAnnotationContext', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'InputConfig', + 'LatLongRect', + 'LocalizedObjectAnnotation', + 'LocationInfo', + 'OperationMetadata', + 'OutputConfig', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'ProductSearchParams', + 'ProductSearchResults', + 'AddProductToProductSetRequest', + 'BatchOperationMetadata', + 'CreateProductRequest', + 'CreateProductSetRequest', + 'CreateReferenceImageRequest', + 'DeleteProductRequest', + 'DeleteProductSetRequest', + 'DeleteReferenceImageRequest', + 'GetProductRequest', + 'GetProductSetRequest', + 'GetReferenceImageRequest', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ListProductsRequest', + 'ListProductsResponse', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'Product', + 'ProductSet', + 'ProductSetPurgeConfig', + 'PurgeProductsRequest', + 'ReferenceImage', + 'RemoveProductFromProductSetRequest', + 'UpdateProductRequest', + 'UpdateProductSetRequest', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1/google/cloud/vision/gapic_version.py b/owl-bot-staging/v1/google/cloud/vision/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1/google/cloud/vision/py.typed b/owl-bot-staging/v1/google/cloud/vision/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/__init__.py b/owl-bot-staging/v1/google/cloud/vision_v1/__init__.py new file mode 100644 index 00000000..900e2db2 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/__init__.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision_v1 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.image_annotator import ImageAnnotatorClient +from .services.image_annotator import ImageAnnotatorAsyncClient +from .services.product_search import ProductSearchClient +from .services.product_search import ProductSearchAsyncClient + +from .types.geometry import BoundingPoly +from .types.geometry import NormalizedVertex +from .types.geometry import Position +from .types.geometry import Vertex +from .types.image_annotator import AnnotateFileRequest +from .types.image_annotator import AnnotateFileResponse +from .types.image_annotator import AnnotateImageRequest +from .types.image_annotator import AnnotateImageResponse +from .types.image_annotator import AsyncAnnotateFileRequest +from .types.image_annotator import AsyncAnnotateFileResponse +from .types.image_annotator import AsyncBatchAnnotateFilesRequest +from .types.image_annotator import AsyncBatchAnnotateFilesResponse +from .types.image_annotator import AsyncBatchAnnotateImagesRequest +from .types.image_annotator import AsyncBatchAnnotateImagesResponse +from .types.image_annotator import BatchAnnotateFilesRequest +from .types.image_annotator import BatchAnnotateFilesResponse +from .types.image_annotator import BatchAnnotateImagesRequest +from .types.image_annotator import BatchAnnotateImagesResponse +from .types.image_annotator import ColorInfo +from .types.image_annotator import CropHint +from .types.image_annotator import CropHintsAnnotation +from .types.image_annotator import CropHintsParams +from .types.image_annotator import DominantColorsAnnotation +from .types.image_annotator import EntityAnnotation +from .types.image_annotator import FaceAnnotation +from .types.image_annotator import Feature +from .types.image_annotator import GcsDestination +from .types.image_annotator import GcsSource +from .types.image_annotator import Image +from .types.image_annotator import ImageAnnotationContext +from .types.image_annotator import ImageContext +from .types.image_annotator import ImageProperties +from .types.image_annotator import ImageSource +from .types.image_annotator import InputConfig +from .types.image_annotator import LatLongRect +from .types.image_annotator import LocalizedObjectAnnotation +from .types.image_annotator import LocationInfo +from .types.image_annotator import OperationMetadata +from .types.image_annotator import OutputConfig +from .types.image_annotator import Property +from .types.image_annotator import SafeSearchAnnotation +from .types.image_annotator import TextDetectionParams +from .types.image_annotator import WebDetectionParams +from .types.image_annotator import Likelihood +from .types.product_search import ProductSearchParams +from .types.product_search import ProductSearchResults +from .types.product_search_service import AddProductToProductSetRequest +from .types.product_search_service import BatchOperationMetadata +from .types.product_search_service import CreateProductRequest +from .types.product_search_service import CreateProductSetRequest +from .types.product_search_service import CreateReferenceImageRequest +from .types.product_search_service import DeleteProductRequest +from .types.product_search_service import DeleteProductSetRequest +from .types.product_search_service import DeleteReferenceImageRequest +from .types.product_search_service import GetProductRequest +from .types.product_search_service import GetProductSetRequest +from .types.product_search_service import GetReferenceImageRequest +from .types.product_search_service import ImportProductSetsGcsSource +from .types.product_search_service import ImportProductSetsInputConfig +from .types.product_search_service import ImportProductSetsRequest +from .types.product_search_service import ImportProductSetsResponse +from .types.product_search_service import ListProductSetsRequest +from .types.product_search_service import ListProductSetsResponse +from .types.product_search_service import ListProductsInProductSetRequest +from .types.product_search_service import ListProductsInProductSetResponse +from .types.product_search_service import ListProductsRequest +from .types.product_search_service import ListProductsResponse +from .types.product_search_service import ListReferenceImagesRequest +from .types.product_search_service import ListReferenceImagesResponse +from .types.product_search_service import Product +from .types.product_search_service import ProductSet +from .types.product_search_service import ProductSetPurgeConfig +from .types.product_search_service import PurgeProductsRequest +from .types.product_search_service import ReferenceImage +from .types.product_search_service import RemoveProductFromProductSetRequest +from .types.product_search_service import UpdateProductRequest +from .types.product_search_service import UpdateProductSetRequest +from .types.text_annotation import Block +from .types.text_annotation import Page +from .types.text_annotation import Paragraph +from .types.text_annotation import Symbol +from .types.text_annotation import TextAnnotation +from .types.text_annotation import Word +from .types.web_detection import WebDetection + +__all__ = ( + 'ImageAnnotatorAsyncClient', + 'ProductSearchAsyncClient', +'AddProductToProductSetRequest', +'AnnotateFileRequest', +'AnnotateFileResponse', +'AnnotateImageRequest', +'AnnotateImageResponse', +'AsyncAnnotateFileRequest', +'AsyncAnnotateFileResponse', +'AsyncBatchAnnotateFilesRequest', +'AsyncBatchAnnotateFilesResponse', +'AsyncBatchAnnotateImagesRequest', +'AsyncBatchAnnotateImagesResponse', +'BatchAnnotateFilesRequest', +'BatchAnnotateFilesResponse', +'BatchAnnotateImagesRequest', +'BatchAnnotateImagesResponse', +'BatchOperationMetadata', +'Block', +'BoundingPoly', +'ColorInfo', +'CreateProductRequest', +'CreateProductSetRequest', +'CreateReferenceImageRequest', +'CropHint', +'CropHintsAnnotation', +'CropHintsParams', +'DeleteProductRequest', +'DeleteProductSetRequest', +'DeleteReferenceImageRequest', +'DominantColorsAnnotation', +'EntityAnnotation', +'FaceAnnotation', +'Feature', +'GcsDestination', +'GcsSource', +'GetProductRequest', +'GetProductSetRequest', +'GetReferenceImageRequest', +'Image', +'ImageAnnotationContext', +'ImageAnnotatorClient', +'ImageContext', +'ImageProperties', +'ImageSource', +'ImportProductSetsGcsSource', +'ImportProductSetsInputConfig', +'ImportProductSetsRequest', +'ImportProductSetsResponse', +'InputConfig', +'LatLongRect', +'Likelihood', +'ListProductSetsRequest', +'ListProductSetsResponse', +'ListProductsInProductSetRequest', +'ListProductsInProductSetResponse', +'ListProductsRequest', +'ListProductsResponse', +'ListReferenceImagesRequest', +'ListReferenceImagesResponse', +'LocalizedObjectAnnotation', +'LocationInfo', +'NormalizedVertex', +'OperationMetadata', +'OutputConfig', +'Page', +'Paragraph', +'Position', +'Product', +'ProductSearchClient', +'ProductSearchParams', +'ProductSearchResults', +'ProductSet', +'ProductSetPurgeConfig', +'Property', +'PurgeProductsRequest', +'ReferenceImage', +'RemoveProductFromProductSetRequest', +'SafeSearchAnnotation', +'Symbol', +'TextAnnotation', +'TextDetectionParams', +'UpdateProductRequest', +'UpdateProductSetRequest', +'Vertex', +'WebDetection', +'WebDetectionParams', +'Word', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/gapic_metadata.json b/owl-bot-staging/v1/google/cloud/vision_v1/gapic_metadata.json new file mode 100644 index 00000000..3d64633b --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/gapic_metadata.json @@ -0,0 +1,392 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.vision_v1", + "protoPackage": "google.cloud.vision.v1", + "schema": "1.0", + "services": { + "ImageAnnotator": { + "clients": { + "grpc": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "AsyncBatchAnnotateImages": { + "methods": [ + "async_batch_annotate_images" + ] + }, + "BatchAnnotateFiles": { + "methods": [ + "batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ImageAnnotatorAsyncClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "AsyncBatchAnnotateImages": { + "methods": [ + "async_batch_annotate_images" + ] + }, + "BatchAnnotateFiles": { + "methods": [ + "batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "rest": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "AsyncBatchAnnotateImages": { + "methods": [ + "async_batch_annotate_images" + ] + }, + "BatchAnnotateFiles": { + "methods": [ + "batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + } + } + }, + "ProductSearch": { + "clients": { + "grpc": { + "libraryClient": "ProductSearchClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ProductSearchAsyncClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + }, + "rest": { + "libraryClient": "ProductSearchClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/gapic_version.py b/owl-bot-staging/v1/google/cloud/vision_v1/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/py.typed b/owl-bot-staging/v1/google/cloud/vision_v1/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/__init__.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/__init__.py new file mode 100644 index 00000000..89a37dc9 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/__init__.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/__init__.py new file mode 100644 index 00000000..ee708f26 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .client import ImageAnnotatorClient +from .async_client import ImageAnnotatorAsyncClient + +__all__ = ( + 'ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/async_client.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/async_client.py new file mode 100644 index 00000000..d2fc1d21 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/async_client.py @@ -0,0 +1,668 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.vision_v1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .client import ImageAnnotatorClient + + +class ImageAnnotatorAsyncClient: + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + _client: ImageAnnotatorClient + + DEFAULT_ENDPOINT = ImageAnnotatorClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ImageAnnotatorClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(ImageAnnotatorClient.product_path) + parse_product_path = staticmethod(ImageAnnotatorClient.parse_product_path) + product_set_path = staticmethod(ImageAnnotatorClient.product_set_path) + parse_product_set_path = staticmethod(ImageAnnotatorClient.parse_product_set_path) + common_billing_account_path = staticmethod(ImageAnnotatorClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ImageAnnotatorClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ImageAnnotatorClient.common_folder_path) + parse_common_folder_path = staticmethod(ImageAnnotatorClient.parse_common_folder_path) + common_organization_path = staticmethod(ImageAnnotatorClient.common_organization_path) + parse_common_organization_path = staticmethod(ImageAnnotatorClient.parse_common_organization_path) + common_project_path = staticmethod(ImageAnnotatorClient.common_project_path) + parse_common_project_path = staticmethod(ImageAnnotatorClient.parse_common_project_path) + common_location_path = staticmethod(ImageAnnotatorClient.common_location_path) + parse_common_location_path = staticmethod(ImageAnnotatorClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_info.__func__(ImageAnnotatorAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_file.__func__(ImageAnnotatorAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ImageAnnotatorClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ImageAnnotatorClient).get_transport_class, type(ImageAnnotatorClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ImageAnnotatorTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ImageAnnotatorClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_batch_annotate_images(): + # Create a client + client = vision_v1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.BatchAnnotateImagesRequest, dict]]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (:class:`MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]`): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.BatchAnnotateImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def batch_annotate_files(self, + request: Optional[Union[image_annotator.BatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateFilesResponse: + r"""Service that performs image detection and annotation + for a batch of files. Now only "application/pdf", + "image/tiff" and "image/gif" are supported. + + This service will extract at most 5 (customers can + specify which 5 in AnnotateFileRequest.pages) frames + (gif) or pages (pdf or tiff) from each file provided and + perform detection and annotation for each image + extracted. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_batch_annotate_files(): + # Create a client + client = vision_v1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1.BatchAnnotateFilesRequest( + ) + + # Make the request + response = await client.batch_annotate_files(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.BatchAnnotateFilesRequest, dict]]): + The request object. A list of requests to annotate files + using the BatchAnnotateFiles API. + requests (:class:`MutableSequence[google.cloud.vision_v1.types.AnnotateFileRequest]`): + Required. The list of file annotation + requests. Right now we support only one + AnnotateFileRequest in + BatchAnnotateFilesRequest. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.BatchAnnotateFilesResponse: + A list of file annotation responses. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.BatchAnnotateFilesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def async_batch_annotate_images(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + output_config: Optional[image_annotator.OutputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Run asynchronous image detection and annotation for a list of + images. + + Progress and results can be retrieved through the + ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateImagesResponse`` (results). + + This service will write image annotation outputs to json files + in customer GCS bucket, each json file containing + BatchAnnotateImagesResponse proto. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_async_batch_annotate_images(): + # Create a client + client = vision_v1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1.AsyncBatchAnnotateImagesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_images(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.AsyncBatchAnnotateImagesRequest, dict]]): + The request object. Request for async image annotation + for a list of images. + requests (:class:`MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]`): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + output_config (:class:`google.cloud.vision_v1.types.OutputConfig`): + Required. The desired output location + and metadata (e.g. format). + + This corresponds to the ``output_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1.types.AsyncBatchAnnotateImagesResponse` + Response to an async batch image annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests, output_config]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.AsyncBatchAnnotateImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if output_config is not None: + request.output_config = output_config + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.async_batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + image_annotator.AsyncBatchAnnotateImagesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + async def async_batch_annotate_files(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AsyncAnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.AsyncBatchAnnotateFilesRequest, dict]]): + The request object. Multiple async file annotation + requests are batched into a single + service call. + requests (:class:`MutableSequence[google.cloud.vision_v1.types.AsyncAnnotateFileRequest]`): + Required. Individual async file + annotation requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1.types.AsyncBatchAnnotateFilesResponse` + Response to an async batch file annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.AsyncBatchAnnotateFilesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.async_batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + image_annotator.AsyncBatchAnnotateFilesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ImageAnnotatorAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorAsyncClient", +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/client.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/client.py new file mode 100644 index 00000000..9681c7de --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/client.py @@ -0,0 +1,853 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import os +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast + +from google.cloud.vision_v1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ImageAnnotatorGrpcTransport +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .transports.rest import ImageAnnotatorRestTransport + + +class ImageAnnotatorClientMeta(type): + """Metaclass for the ImageAnnotator client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] + _transport_registry["grpc"] = ImageAnnotatorGrpcTransport + _transport_registry["grpc_asyncio"] = ImageAnnotatorGrpcAsyncIOTransport + _transport_registry["rest"] = ImageAnnotatorRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ImageAnnotatorTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ImageAnnotatorClient(metaclass=ImageAnnotatorClientMeta): + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "vision.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_set_path(project: str,location: str,product_set: str,) -> str: + """Returns a fully-qualified product_set string.""" + return "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + + @staticmethod + def parse_product_set_path(path: str) -> Dict[str,str]: + """Parses a product_set path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/productSets/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ImageAnnotatorTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ImageAnnotatorTransport): + # transport is a ImageAnnotatorTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_batch_annotate_images(): + # Create a client + client = vision_v1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.BatchAnnotateImagesRequest, dict]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.BatchAnnotateImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.BatchAnnotateImagesRequest): + request = image_annotator.BatchAnnotateImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_annotate_images] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_annotate_files(self, + request: Optional[Union[image_annotator.BatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateFilesResponse: + r"""Service that performs image detection and annotation + for a batch of files. Now only "application/pdf", + "image/tiff" and "image/gif" are supported. + + This service will extract at most 5 (customers can + specify which 5 in AnnotateFileRequest.pages) frames + (gif) or pages (pdf or tiff) from each file provided and + perform detection and annotation for each image + extracted. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_batch_annotate_files(): + # Create a client + client = vision_v1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1.BatchAnnotateFilesRequest( + ) + + # Make the request + response = client.batch_annotate_files(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.BatchAnnotateFilesRequest, dict]): + The request object. A list of requests to annotate files + using the BatchAnnotateFiles API. + requests (MutableSequence[google.cloud.vision_v1.types.AnnotateFileRequest]): + Required. The list of file annotation + requests. Right now we support only one + AnnotateFileRequest in + BatchAnnotateFilesRequest. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.BatchAnnotateFilesResponse: + A list of file annotation responses. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.BatchAnnotateFilesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.BatchAnnotateFilesRequest): + request = image_annotator.BatchAnnotateFilesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_annotate_files] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def async_batch_annotate_images(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + output_config: Optional[image_annotator.OutputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Run asynchronous image detection and annotation for a list of + images. + + Progress and results can be retrieved through the + ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateImagesResponse`` (results). + + This service will write image annotation outputs to json files + in customer GCS bucket, each json file containing + BatchAnnotateImagesResponse proto. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_async_batch_annotate_images(): + # Create a client + client = vision_v1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1.AsyncBatchAnnotateImagesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_images(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.AsyncBatchAnnotateImagesRequest, dict]): + The request object. Request for async image annotation + for a list of images. + requests (MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + output_config (google.cloud.vision_v1.types.OutputConfig): + Required. The desired output location + and metadata (e.g. format). + + This corresponds to the ``output_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1.types.AsyncBatchAnnotateImagesResponse` + Response to an async batch image annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests, output_config]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.AsyncBatchAnnotateImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.AsyncBatchAnnotateImagesRequest): + request = image_annotator.AsyncBatchAnnotateImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + if output_config is not None: + request.output_config = output_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.async_batch_annotate_images] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + image_annotator.AsyncBatchAnnotateImagesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + def async_batch_annotate_files(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AsyncAnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.AsyncBatchAnnotateFilesRequest, dict]): + The request object. Multiple async file annotation + requests are batched into a single + service call. + requests (MutableSequence[google.cloud.vision_v1.types.AsyncAnnotateFileRequest]): + Required. Individual async file + annotation requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1.types.AsyncBatchAnnotateFilesResponse` + Response to an async batch file annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.AsyncBatchAnnotateFilesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.AsyncBatchAnnotateFilesRequest): + request = image_annotator.AsyncBatchAnnotateFilesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.async_batch_annotate_files] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + image_annotator.AsyncBatchAnnotateFilesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ImageAnnotatorClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorClient", +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/__init__.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/__init__.py new file mode 100644 index 00000000..ad6cf948 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +from typing import Dict, Type + +from .base import ImageAnnotatorTransport +from .grpc import ImageAnnotatorGrpcTransport +from .grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .rest import ImageAnnotatorRestTransport +from .rest import ImageAnnotatorRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] +_transport_registry['grpc'] = ImageAnnotatorGrpcTransport +_transport_registry['grpc_asyncio'] = ImageAnnotatorGrpcAsyncIOTransport +_transport_registry['rest'] = ImageAnnotatorRestTransport + +__all__ = ( + 'ImageAnnotatorTransport', + 'ImageAnnotatorGrpcTransport', + 'ImageAnnotatorGrpcAsyncIOTransport', + 'ImageAnnotatorRestTransport', + 'ImageAnnotatorRestInterceptor', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/base.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/base.py new file mode 100644 index 00000000..dd39373f --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/base.py @@ -0,0 +1,226 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.vision_v1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.vision_v1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ImageAnnotatorTransport(abc.ABC): + """Abstract transport class for ImageAnnotator.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', + ) + + DEFAULT_HOST: str = 'vision.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience(api_audience if api_audience else host) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.batch_annotate_images: gapic_v1.method.wrap_method( + self.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.batch_annotate_files: gapic_v1.method.wrap_method( + self.batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.async_batch_annotate_images: gapic_v1.method.wrap_method( + self.async_batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.async_batch_annotate_files: gapic_v1.method.wrap_method( + self.async_batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Union[ + image_annotator.BatchAnnotateImagesResponse, + Awaitable[image_annotator.BatchAnnotateImagesResponse] + ]]: + raise NotImplementedError() + + @property + def batch_annotate_files(self) -> Callable[ + [image_annotator.BatchAnnotateFilesRequest], + Union[ + image_annotator.BatchAnnotateFilesResponse, + Awaitable[image_annotator.BatchAnnotateFilesResponse] + ]]: + raise NotImplementedError() + + @property + def async_batch_annotate_images(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateImagesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ImageAnnotatorTransport', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/grpc.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/grpc.py new file mode 100644 index 00000000..628a0da5 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.vision_v1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO + + +class ImageAnnotatorGrpcTransport(ImageAnnotatorTransport): + """gRPC backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + ~.BatchAnnotateImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + @property + def batch_annotate_files(self) -> Callable[ + [image_annotator.BatchAnnotateFilesRequest], + image_annotator.BatchAnnotateFilesResponse]: + r"""Return a callable for the batch annotate files method over gRPC. + + Service that performs image detection and annotation + for a batch of files. Now only "application/pdf", + "image/tiff" and "image/gif" are supported. + + This service will extract at most 5 (customers can + specify which 5 in AnnotateFileRequest.pages) frames + (gif) or pages (pdf or tiff) from each file provided and + perform detection and annotation for each image + extracted. + + Returns: + Callable[[~.BatchAnnotateFilesRequest], + ~.BatchAnnotateFilesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_files' not in self._stubs: + self._stubs['batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ImageAnnotator/BatchAnnotateFiles', + request_serializer=image_annotator.BatchAnnotateFilesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateFilesResponse.deserialize, + ) + return self._stubs['batch_annotate_files'] + + @property + def async_batch_annotate_images(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateImagesRequest], + operations_pb2.Operation]: + r"""Return a callable for the async batch annotate images method over gRPC. + + Run asynchronous image detection and annotation for a list of + images. + + Progress and results can be retrieved through the + ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateImagesResponse`` (results). + + This service will write image annotation outputs to json files + in customer GCS bucket, each json file containing + BatchAnnotateImagesResponse proto. + + Returns: + Callable[[~.AsyncBatchAnnotateImagesRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_images' not in self._stubs: + self._stubs['async_batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ImageAnnotator/AsyncBatchAnnotateImages', + request_serializer=image_annotator.AsyncBatchAnnotateImagesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_images'] + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + operations_pb2.Operation]: + r"""Return a callable for the async batch annotate files method over gRPC. + + Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + Returns: + Callable[[~.AsyncBatchAnnotateFilesRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_files' not in self._stubs: + self._stubs['async_batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ImageAnnotator/AsyncBatchAnnotateFiles', + request_serializer=image_annotator.AsyncBatchAnnotateFilesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_files'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ImageAnnotatorGrpcTransport', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/grpc_asyncio.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/grpc_asyncio.py new file mode 100644 index 00000000..a6a1cdfd --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/grpc_asyncio.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.vision_v1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .grpc import ImageAnnotatorGrpcTransport + + +class ImageAnnotatorGrpcAsyncIOTransport(ImageAnnotatorTransport): + """gRPC AsyncIO backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Awaitable[image_annotator.BatchAnnotateImagesResponse]]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + Awaitable[~.BatchAnnotateImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + @property + def batch_annotate_files(self) -> Callable[ + [image_annotator.BatchAnnotateFilesRequest], + Awaitable[image_annotator.BatchAnnotateFilesResponse]]: + r"""Return a callable for the batch annotate files method over gRPC. + + Service that performs image detection and annotation + for a batch of files. Now only "application/pdf", + "image/tiff" and "image/gif" are supported. + + This service will extract at most 5 (customers can + specify which 5 in AnnotateFileRequest.pages) frames + (gif) or pages (pdf or tiff) from each file provided and + perform detection and annotation for each image + extracted. + + Returns: + Callable[[~.BatchAnnotateFilesRequest], + Awaitable[~.BatchAnnotateFilesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_files' not in self._stubs: + self._stubs['batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ImageAnnotator/BatchAnnotateFiles', + request_serializer=image_annotator.BatchAnnotateFilesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateFilesResponse.deserialize, + ) + return self._stubs['batch_annotate_files'] + + @property + def async_batch_annotate_images(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateImagesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the async batch annotate images method over gRPC. + + Run asynchronous image detection and annotation for a list of + images. + + Progress and results can be retrieved through the + ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateImagesResponse`` (results). + + This service will write image annotation outputs to json files + in customer GCS bucket, each json file containing + BatchAnnotateImagesResponse proto. + + Returns: + Callable[[~.AsyncBatchAnnotateImagesRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_images' not in self._stubs: + self._stubs['async_batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ImageAnnotator/AsyncBatchAnnotateImages', + request_serializer=image_annotator.AsyncBatchAnnotateImagesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_images'] + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the async batch annotate files method over gRPC. + + Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + Returns: + Callable[[~.AsyncBatchAnnotateFilesRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_files' not in self._stubs: + self._stubs['async_batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ImageAnnotator/AsyncBatchAnnotateFiles', + request_serializer=image_annotator.AsyncBatchAnnotateFilesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_files'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ImageAnnotatorGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/rest.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/rest.py new file mode 100644 index 00000000..7d9bc42f --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/image_annotator/transports/rest.py @@ -0,0 +1,754 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.auth.transport.requests import AuthorizedSession # type: ignore +import json # type: ignore +import grpc # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.api_core import rest_helpers +from google.api_core import rest_streaming +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from google.api_core import operations_v1 +from requests import __version__ as requests_version +import dataclasses +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.cloud.vision_v1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore + +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ImageAnnotatorRestInterceptor: + """Interceptor for ImageAnnotator. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ImageAnnotatorRestTransport. + + .. code-block:: python + class MyCustomImageAnnotatorInterceptor(ImageAnnotatorRestInterceptor): + def pre_async_batch_annotate_files(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_async_batch_annotate_files(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_async_batch_annotate_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_async_batch_annotate_images(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_annotate_files(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_annotate_files(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_annotate_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_annotate_images(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ImageAnnotatorRestTransport(interceptor=MyCustomImageAnnotatorInterceptor()) + client = ImageAnnotatorClient(transport=transport) + + + """ + def pre_async_batch_annotate_files(self, request: image_annotator.AsyncBatchAnnotateFilesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.AsyncBatchAnnotateFilesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for async_batch_annotate_files + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_async_batch_annotate_files(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for async_batch_annotate_files + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + def pre_async_batch_annotate_images(self, request: image_annotator.AsyncBatchAnnotateImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.AsyncBatchAnnotateImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for async_batch_annotate_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_async_batch_annotate_images(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for async_batch_annotate_images + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + def pre_batch_annotate_files(self, request: image_annotator.BatchAnnotateFilesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.BatchAnnotateFilesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_annotate_files + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_batch_annotate_files(self, response: image_annotator.BatchAnnotateFilesResponse) -> image_annotator.BatchAnnotateFilesResponse: + """Post-rpc interceptor for batch_annotate_files + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + def pre_batch_annotate_images(self, request: image_annotator.BatchAnnotateImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.BatchAnnotateImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_batch_annotate_images(self, response: image_annotator.BatchAnnotateImagesResponse) -> image_annotator.BatchAnnotateImagesResponse: + """Post-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ImageAnnotatorRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ImageAnnotatorRestInterceptor + + +class ImageAnnotatorRestTransport(ImageAnnotatorTransport): + """REST backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[ + ], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + interceptor: Optional[ImageAnnotatorRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError(f"Unexpected hostname structure: {host}") # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ImageAnnotatorRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + 'google.longrunning.Operations.GetOperation': [ + { + 'method': 'get', + 'uri': '/v1/{name=projects/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v1/{name=operations/*}', + }, + { + 'method': 'get', + 'uri': '/v1/{name=locations/*/operations/*}', + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AsyncBatchAnnotateFiles(ImageAnnotatorRestStub): + def __hash__(self): + return hash("AsyncBatchAnnotateFiles") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.AsyncBatchAnnotateFilesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the async batch annotate + files method over HTTP. + + Args: + request (~.image_annotator.AsyncBatchAnnotateFilesRequest): + The request object. Multiple async file annotation + requests are batched into a single + service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/files:asyncBatchAnnotate', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/files:asyncBatchAnnotate', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*}/files:asyncBatchAnnotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_async_batch_annotate_files(request, metadata) + pb_request = image_annotator.AsyncBatchAnnotateFilesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_async_batch_annotate_files(resp) + return resp + + class _AsyncBatchAnnotateImages(ImageAnnotatorRestStub): + def __hash__(self): + return hash("AsyncBatchAnnotateImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.AsyncBatchAnnotateImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the async batch annotate + images method over HTTP. + + Args: + request (~.image_annotator.AsyncBatchAnnotateImagesRequest): + The request object. Request for async image annotation + for a list of images. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/images:asyncBatchAnnotate', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/images:asyncBatchAnnotate', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*}/images:asyncBatchAnnotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_async_batch_annotate_images(request, metadata) + pb_request = image_annotator.AsyncBatchAnnotateImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_async_batch_annotate_images(resp) + return resp + + class _BatchAnnotateFiles(ImageAnnotatorRestStub): + def __hash__(self): + return hash("BatchAnnotateFiles") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.BatchAnnotateFilesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> image_annotator.BatchAnnotateFilesResponse: + r"""Call the batch annotate files method over HTTP. + + Args: + request (~.image_annotator.BatchAnnotateFilesRequest): + The request object. A list of requests to annotate files + using the BatchAnnotateFiles API. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.image_annotator.BatchAnnotateFilesResponse: + A list of file annotation responses. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/files:annotate', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/files:annotate', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*}/files:annotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_annotate_files(request, metadata) + pb_request = image_annotator.BatchAnnotateFilesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = image_annotator.BatchAnnotateFilesResponse() + pb_resp = image_annotator.BatchAnnotateFilesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_annotate_files(resp) + return resp + + class _BatchAnnotateImages(ImageAnnotatorRestStub): + def __hash__(self): + return hash("BatchAnnotateImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.BatchAnnotateImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Call the batch annotate images method over HTTP. + + Args: + request (~.image_annotator.BatchAnnotateImagesRequest): + The request object. Multiple image annotation requests + are batched into a single service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.image_annotator.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/images:annotate', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/images:annotate', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*}/images:annotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_annotate_images(request, metadata) + pb_request = image_annotator.BatchAnnotateImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = image_annotator.BatchAnnotateImagesResponse() + pb_resp = image_annotator.BatchAnnotateImagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_annotate_images(resp) + return resp + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AsyncBatchAnnotateFiles(self._session, self._host, self._interceptor) # type: ignore + + @property + def async_batch_annotate_images(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateImagesRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AsyncBatchAnnotateImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_annotate_files(self) -> Callable[ + [image_annotator.BatchAnnotateFilesRequest], + image_annotator.BatchAnnotateFilesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchAnnotateFiles(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchAnnotateImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ImageAnnotatorRestTransport', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/__init__.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/__init__.py new file mode 100644 index 00000000..f48c4b91 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .client import ProductSearchClient +from .async_client import ProductSearchAsyncClient + +__all__ = ( + 'ProductSearchClient', + 'ProductSearchAsyncClient', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/async_client.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/async_client.py new file mode 100644 index 00000000..62dadd82 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/async_client.py @@ -0,0 +1,2615 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.vision_v1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1.services.product_search import pagers +from google.cloud.vision_v1.types import geometry +from google.cloud.vision_v1.types import product_search_service +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .client import ProductSearchClient + + +class ProductSearchAsyncClient: + """Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1.ProductSet] resources, named + ``projects/*/locations/*/productSets/*``, which acts as a way to + put different products into groups to limit identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1.Product] has a collection + of [ReferenceImage][google.cloud.vision.v1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + """ + + _client: ProductSearchClient + + DEFAULT_ENDPOINT = ProductSearchClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ProductSearchClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(ProductSearchClient.product_path) + parse_product_path = staticmethod(ProductSearchClient.parse_product_path) + product_set_path = staticmethod(ProductSearchClient.product_set_path) + parse_product_set_path = staticmethod(ProductSearchClient.parse_product_set_path) + reference_image_path = staticmethod(ProductSearchClient.reference_image_path) + parse_reference_image_path = staticmethod(ProductSearchClient.parse_reference_image_path) + common_billing_account_path = staticmethod(ProductSearchClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ProductSearchClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ProductSearchClient.common_folder_path) + parse_common_folder_path = staticmethod(ProductSearchClient.parse_common_folder_path) + common_organization_path = staticmethod(ProductSearchClient.common_organization_path) + parse_common_organization_path = staticmethod(ProductSearchClient.parse_common_organization_path) + common_project_path = staticmethod(ProductSearchClient.common_project_path) + parse_common_project_path = staticmethod(ProductSearchClient.parse_common_project_path) + common_location_path = staticmethod(ProductSearchClient.common_location_path) + parse_common_location_path = staticmethod(ProductSearchClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchAsyncClient: The constructed client. + """ + return ProductSearchClient.from_service_account_info.__func__(ProductSearchAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchAsyncClient: The constructed client. + """ + return ProductSearchClient.from_service_account_file.__func__(ProductSearchAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ProductSearchClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductSearchTransport: + """Returns the transport used by the client instance. + + Returns: + ProductSearchTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ProductSearchClient).get_transport_class, type(ProductSearchClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ProductSearchTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product search client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ProductSearchTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ProductSearchClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_product_set(self, + request: Optional[Union[product_search_service.CreateProductSetRequest, dict]] = None, + *, + parent: Optional[str] = None, + product_set: Optional[product_search_service.ProductSet] = None, + product_set_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_create_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.CreateProductSetRequest, dict]]): + The request object. Request message for the ``CreateProductSet`` method. + parent (:class:`str`): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set (:class:`google.cloud.vision_v1.types.ProductSet`): + Required. The ProductSet to create. + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set_id (:class:`str`): + A user-supplied resource id for this ProductSet. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_set_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product_set, product_set_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product_set is not None: + request.product_set = product_set + if product_set_id is not None: + request.product_set_id = product_set_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_product_sets(self, + request: Optional[Union[product_search_service.ListProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductSetsAsyncPager: + r"""Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_list_product_sets(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.ListProductSetsRequest, dict]]): + The request object. Request message for the ``ListProductSets`` method. + parent (:class:`str`): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.services.product_search.pagers.ListProductSetsAsyncPager: + Response message for the ListProductSets method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductSetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductSetsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_product_set(self, + request: Optional[Union[product_search_service.GetProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_get_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.GetProductSetRequest, dict]]): + The request object. Request message for the ``GetProductSet`` method. + name (:class:`str`): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_product_set(self, + request: Optional[Union[product_search_service.UpdateProductSetRequest, dict]] = None, + *, + product_set: Optional[product_search_service.ProductSet] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_update_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.UpdateProductSetRequest( + ) + + # Make the request + response = await client.update_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.UpdateProductSetRequest, dict]]): + The request object. Request message for the ``UpdateProductSet`` method. + product_set (:class:`google.cloud.vision_v1.types.ProductSet`): + Required. The ProductSet resource + which replaces the one on the server. + + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask path is ``display_name``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product_set, update_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.UpdateProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product_set is not None: + request.product_set = product_set + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product_set.name", request.product_set.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_product_set(self, + request: Optional[Union[product_search_service.DeleteProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a ProductSet. Products and + ReferenceImages in the ProductSet are not deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_delete_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + await client.delete_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.DeleteProductSetRequest, dict]]): + The request object. Request message for the ``DeleteProductSet`` method. + name (:class:`str`): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def create_product(self, + request: Optional[Union[product_search_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[product_search_service.Product] = None, + product_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_create_product(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.CreateProductRequest, dict]]): + The request object. Request message for the ``CreateProduct`` method. + parent (:class:`str`): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`google.cloud.vision_v1.types.Product`): + Required. The product to create. + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_id (:class:`str`): + A user-supplied resource id for this Product. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product, product_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product is not None: + request.product = product + if product_id is not None: + request.product_id = product_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_products(self, + request: Optional[Union[product_search_service.ListProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsAsyncPager: + r"""Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_list_products(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.ListProductsRequest, dict]]): + The request object. Request message for the ``ListProducts`` method. + parent (:class:`str`): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.services.product_search.pagers.ListProductsAsyncPager: + Response message for the ListProducts method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_products, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_product(self, + request: Optional[Union[product_search_service.GetProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_get_product(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.GetProductRequest, dict]]): + The request object. Request message for the ``GetProduct`` method. + name (:class:`str`): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_product(self, + request: Optional[Union[product_search_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[product_search_service.Product] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Makes changes to a Product resource. Only the ``display_name``, + ``description``, and ``labels`` fields can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_update_product(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.UpdateProductRequest( + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.UpdateProductRequest, dict]]): + The request object. Request message for the ``UpdateProduct`` method. + product (:class:`google.cloud.vision_v1.types.Product`): + Required. The Product resource which + replaces the one on the server. + product.name is immutable. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask paths include ``product_labels``, ``display_name``, + and ``description``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product, update_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.UpdateProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product.name", request.product.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_product(self, + request: Optional[Union[product_search_service.DeleteProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a product and its reference + images. + Metadata of the product and all its images will be + deleted right away, but search queries against + ProductSets containing the product may still work until + all related caches are refreshed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_delete_product(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.DeleteProductRequest, dict]]): + The request object. Request message for the ``DeleteProduct`` method. + name (:class:`str`): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def create_reference_image(self, + request: Optional[Union[product_search_service.CreateReferenceImageRequest, dict]] = None, + *, + parent: Optional[str] = None, + reference_image: Optional[product_search_service.ReferenceImage] = None, + reference_image_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_create_reference_image(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + reference_image = vision_v1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = await client.create_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.CreateReferenceImageRequest, dict]]): + The request object. Request message for the ``CreateReferenceImage`` method. + parent (:class:`str`): + Required. Resource name of the product in which to + create the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image (:class:`google.cloud.vision_v1.types.ReferenceImage`): + Required. The reference image to + create. If an image ID is specified, it + is ignored. + + This corresponds to the ``reference_image`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image_id (:class:`str`): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value + as the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``reference_image_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, reference_image, reference_image_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if reference_image is not None: + request.reference_image = reference_image + if reference_image_id is not None: + request.reference_image_id = reference_image_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_reference_image(self, + request: Optional[Union[product_search_service.DeleteReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a reference image. + + The image metadata will be deleted right away, but + search queries against ProductSets containing the image + may still work until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_delete_reference_image(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + await client.delete_reference_image(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.DeleteReferenceImageRequest, dict]]): + The request object. Request message for the ``DeleteReferenceImage`` method. + name (:class:`str`): + Required. The resource name of the reference image to + delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_reference_images(self, + request: Optional[Union[product_search_service.ListReferenceImagesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListReferenceImagesAsyncPager: + r"""Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_list_reference_images(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.ListReferenceImagesRequest, dict]]): + The request object. Request message for the ``ListReferenceImages`` method. + parent (:class:`str`): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.services.product_search.pagers.ListReferenceImagesAsyncPager: + Response message for the ListReferenceImages method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListReferenceImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_reference_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListReferenceImagesAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_reference_image(self, + request: Optional[Union[product_search_service.GetReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_get_reference_image(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = await client.get_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.GetReferenceImageRequest, dict]]): + The request object. Request message for the ``GetReferenceImage`` method. + name (:class:`str`): + Required. The resource name of the ReferenceImage to + get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_product_to_product_set(self, + request: Optional[Union[product_search_service.AddProductToProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_add_product_to_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.add_product_to_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.AddProductToProductSetRequest, dict]]): + The request object. Request message for the ``AddProductToProductSet`` + method. + name (:class:`str`): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`str`): + Required. The resource name for the Product to be added + to this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.AddProductToProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.add_product_to_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def remove_product_from_product_set(self, + request: Optional[Union[product_search_service.RemoveProductFromProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Removes a Product from the specified ProductSet. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.remove_product_from_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.RemoveProductFromProductSetRequest, dict]]): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + name (:class:`str`): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`str`): + Required. The resource name for the Product to be + removed from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.RemoveProductFromProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.remove_product_from_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_products_in_product_set(self, + request: Optional[Union[product_search_service.ListProductsInProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsInProductSetAsyncPager: + r"""Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_list_products_in_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.ListProductsInProductSetRequest, dict]]): + The request object. Request message for the ``ListProductsInProductSet`` + method. + name (:class:`str`): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.services.product_search.pagers.ListProductsInProductSetAsyncPager: + Response message for the ListProductsInProductSet + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductsInProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_products_in_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductsInProductSetAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def import_product_sets(self, + request: Optional[Union[product_search_service.ImportProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + input_config: Optional[product_search_service.ImportProductSetsInputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1.ImportProductSetsGcsSource.csv_file_uri]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_import_product_sets(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.ImportProductSetsRequest, dict]]): + The request object. Request message for the ``ImportProductSets`` method. + parent (:class:`str`): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + input_config (:class:`google.cloud.vision_v1.types.ImportProductSetsInputConfig`): + Required. The input content for the + list of requests. + + This corresponds to the ``input_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1.types.ImportProductSetsResponse` + Response message for the ImportProductSets method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, input_config]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ImportProductSetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if input_config is not None: + request.input_config = input_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + product_search_service.ImportProductSetsResponse, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + async def purge_products(self, + request: Optional[Union[product_search_service.PurgeProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Asynchronous API to delete all Products in a ProductSet or all + Products that are in no ProductSet. + + If a Product is a member of the specified ProductSet in addition + to other ProductSets, the Product will still be deleted. + + It is recommended to not delete the specified ProductSet until + after this operation has completed. It is also recommended to + not add any of the Products involved in the batch delete to a + new ProductSet while this operation is running because those + Products may still end up deleted. + + It's not possible to undo the PurgeProducts operation. + Therefore, it is recommended to keep the csv files used in + ImportProductSets (if that was how you originally built the + Product Set) before starting PurgeProducts, in case you need to + re-import the data after deletion. + + If the plan is to purge all of the Products from a ProductSet + and then re-use the empty ProductSet to re-import new Products + into the empty ProductSet, you must wait until the PurgeProducts + operation has finished for that ProductSet. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + async def sample_purge_products(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.PurgeProductsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.purge_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1.types.PurgeProductsRequest, dict]]): + The request object. Request message for the ``PurgeProducts`` method. + parent (:class:`str`): + Required. The project and location in which the Products + should be deleted. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.PurgeProductsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.purge_products, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ProductSearchAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductSearchAsyncClient", +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/client.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/client.py new file mode 100644 index 00000000..e037ea07 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/client.py @@ -0,0 +1,2714 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import os +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast + +from google.cloud.vision_v1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1.services.product_search import pagers +from google.cloud.vision_v1.types import geometry +from google.cloud.vision_v1.types import product_search_service +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ProductSearchGrpcTransport +from .transports.grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .transports.rest import ProductSearchRestTransport + + +class ProductSearchClientMeta(type): + """Metaclass for the ProductSearch client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ProductSearchTransport]] + _transport_registry["grpc"] = ProductSearchGrpcTransport + _transport_registry["grpc_asyncio"] = ProductSearchGrpcAsyncIOTransport + _transport_registry["rest"] = ProductSearchRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ProductSearchTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ProductSearchClient(metaclass=ProductSearchClientMeta): + """Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1.ProductSet] resources, named + ``projects/*/locations/*/productSets/*``, which acts as a way to + put different products into groups to limit identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1.Product] has a collection + of [ReferenceImage][google.cloud.vision.v1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "vision.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ProductSearchTransport: + """Returns the transport used by the client instance. + + Returns: + ProductSearchTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_set_path(project: str,location: str,product_set: str,) -> str: + """Returns a fully-qualified product_set string.""" + return "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + + @staticmethod + def parse_product_set_path(path: str) -> Dict[str,str]: + """Parses a product_set path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/productSets/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def reference_image_path(project: str,location: str,product: str,reference_image: str,) -> str: + """Returns a fully-qualified reference_image string.""" + return "projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}".format(project=project, location=location, product=product, reference_image=reference_image, ) + + @staticmethod + def parse_reference_image_path(path: str) -> Dict[str,str]: + """Parses a reference_image path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)/referenceImages/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ProductSearchTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product search client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ProductSearchTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ProductSearchTransport): + # transport is a ProductSearchTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def create_product_set(self, + request: Optional[Union[product_search_service.CreateProductSetRequest, dict]] = None, + *, + parent: Optional[str] = None, + product_set: Optional[product_search_service.ProductSet] = None, + product_set_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_create_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.CreateProductSetRequest, dict]): + The request object. Request message for the ``CreateProductSet`` method. + parent (str): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set (google.cloud.vision_v1.types.ProductSet): + Required. The ProductSet to create. + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set_id (str): + A user-supplied resource id for this ProductSet. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_set_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product_set, product_set_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateProductSetRequest): + request = product_search_service.CreateProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product_set is not None: + request.product_set = product_set + if product_set_id is not None: + request.product_set_id = product_set_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_product_sets(self, + request: Optional[Union[product_search_service.ListProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductSetsPager: + r"""Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_list_product_sets(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.ListProductSetsRequest, dict]): + The request object. Request message for the ``ListProductSets`` method. + parent (str): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.services.product_search.pagers.ListProductSetsPager: + Response message for the ListProductSets method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductSetsRequest): + request = product_search_service.ListProductSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_product_sets] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductSetsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_product_set(self, + request: Optional[Union[product_search_service.GetProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_get_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = client.get_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.GetProductSetRequest, dict]): + The request object. Request message for the ``GetProductSet`` method. + name (str): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetProductSetRequest): + request = product_search_service.GetProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_product_set(self, + request: Optional[Union[product_search_service.UpdateProductSetRequest, dict]] = None, + *, + product_set: Optional[product_search_service.ProductSet] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_update_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.UpdateProductSetRequest( + ) + + # Make the request + response = client.update_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.UpdateProductSetRequest, dict]): + The request object. Request message for the ``UpdateProductSet`` method. + product_set (google.cloud.vision_v1.types.ProductSet): + Required. The ProductSet resource + which replaces the one on the server. + + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask path is ``display_name``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product_set, update_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.UpdateProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.UpdateProductSetRequest): + request = product_search_service.UpdateProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product_set is not None: + request.product_set = product_set + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product_set.name", request.product_set.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_product_set(self, + request: Optional[Union[product_search_service.DeleteProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a ProductSet. Products and + ReferenceImages in the ProductSet are not deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_delete_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + client.delete_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1.types.DeleteProductSetRequest, dict]): + The request object. Request message for the ``DeleteProductSet`` method. + name (str): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteProductSetRequest): + request = product_search_service.DeleteProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def create_product(self, + request: Optional[Union[product_search_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[product_search_service.Product] = None, + product_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_create_product(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.CreateProductRequest, dict]): + The request object. Request message for the ``CreateProduct`` method. + parent (str): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (google.cloud.vision_v1.types.Product): + Required. The product to create. + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_id (str): + A user-supplied resource id for this Product. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product, product_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateProductRequest): + request = product_search_service.CreateProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product is not None: + request.product = product + if product_id is not None: + request.product_id = product_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_products(self, + request: Optional[Union[product_search_service.ListProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsPager: + r"""Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_list_products(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.ListProductsRequest, dict]): + The request object. Request message for the ``ListProducts`` method. + parent (str): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.services.product_search.pagers.ListProductsPager: + Response message for the ListProducts method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductsRequest): + request = product_search_service.ListProductsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_products] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_product(self, + request: Optional[Union[product_search_service.GetProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_get_product(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.GetProductRequest, dict]): + The request object. Request message for the ``GetProduct`` method. + name (str): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetProductRequest): + request = product_search_service.GetProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_product(self, + request: Optional[Union[product_search_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[product_search_service.Product] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Makes changes to a Product resource. Only the ``display_name``, + ``description``, and ``labels`` fields can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_update_product(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.UpdateProductRequest( + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.UpdateProductRequest, dict]): + The request object. Request message for the ``UpdateProduct`` method. + product (google.cloud.vision_v1.types.Product): + Required. The Product resource which + replaces the one on the server. + product.name is immutable. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask paths include ``product_labels``, ``display_name``, + and ``description``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product, update_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.UpdateProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.UpdateProductRequest): + request = product_search_service.UpdateProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product.name", request.product.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_product(self, + request: Optional[Union[product_search_service.DeleteProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a product and its reference + images. + Metadata of the product and all its images will be + deleted right away, but search queries against + ProductSets containing the product may still work until + all related caches are refreshed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_delete_product(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + Args: + request (Union[google.cloud.vision_v1.types.DeleteProductRequest, dict]): + The request object. Request message for the ``DeleteProduct`` method. + name (str): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteProductRequest): + request = product_search_service.DeleteProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def create_reference_image(self, + request: Optional[Union[product_search_service.CreateReferenceImageRequest, dict]] = None, + *, + parent: Optional[str] = None, + reference_image: Optional[product_search_service.ReferenceImage] = None, + reference_image_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_create_reference_image(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + reference_image = vision_v1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = client.create_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.CreateReferenceImageRequest, dict]): + The request object. Request message for the ``CreateReferenceImage`` method. + parent (str): + Required. Resource name of the product in which to + create the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image (google.cloud.vision_v1.types.ReferenceImage): + Required. The reference image to + create. If an image ID is specified, it + is ignored. + + This corresponds to the ``reference_image`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image_id (str): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value + as the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``reference_image_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, reference_image, reference_image_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateReferenceImageRequest): + request = product_search_service.CreateReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if reference_image is not None: + request.reference_image = reference_image + if reference_image_id is not None: + request.reference_image_id = reference_image_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_reference_image(self, + request: Optional[Union[product_search_service.DeleteReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a reference image. + + The image metadata will be deleted right away, but + search queries against ProductSets containing the image + may still work until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_delete_reference_image(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + client.delete_reference_image(request=request) + + Args: + request (Union[google.cloud.vision_v1.types.DeleteReferenceImageRequest, dict]): + The request object. Request message for the ``DeleteReferenceImage`` method. + name (str): + Required. The resource name of the reference image to + delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteReferenceImageRequest): + request = product_search_service.DeleteReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def list_reference_images(self, + request: Optional[Union[product_search_service.ListReferenceImagesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListReferenceImagesPager: + r"""Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_list_reference_images(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.ListReferenceImagesRequest, dict]): + The request object. Request message for the ``ListReferenceImages`` method. + parent (str): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.services.product_search.pagers.ListReferenceImagesPager: + Response message for the ListReferenceImages method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListReferenceImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListReferenceImagesRequest): + request = product_search_service.ListReferenceImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_reference_images] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListReferenceImagesPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_reference_image(self, + request: Optional[Union[product_search_service.GetReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_get_reference_image(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = client.get_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.GetReferenceImageRequest, dict]): + The request object. Request message for the ``GetReferenceImage`` method. + name (str): + Required. The resource name of the ReferenceImage to + get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetReferenceImageRequest): + request = product_search_service.GetReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_product_to_product_set(self, + request: Optional[Union[product_search_service.AddProductToProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_add_product_to_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.add_product_to_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1.types.AddProductToProductSetRequest, dict]): + The request object. Request message for the ``AddProductToProductSet`` + method. + name (str): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (str): + Required. The resource name for the Product to be added + to this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.AddProductToProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.AddProductToProductSetRequest): + request = product_search_service.AddProductToProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_product_to_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def remove_product_from_product_set(self, + request: Optional[Union[product_search_service.RemoveProductFromProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Removes a Product from the specified ProductSet. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.remove_product_from_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1.types.RemoveProductFromProductSetRequest, dict]): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + name (str): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (str): + Required. The resource name for the Product to be + removed from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.RemoveProductFromProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.RemoveProductFromProductSetRequest): + request = product_search_service.RemoveProductFromProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_product_from_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def list_products_in_product_set(self, + request: Optional[Union[product_search_service.ListProductsInProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsInProductSetPager: + r"""Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_list_products_in_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.ListProductsInProductSetRequest, dict]): + The request object. Request message for the ``ListProductsInProductSet`` + method. + name (str): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1.services.product_search.pagers.ListProductsInProductSetPager: + Response message for the ListProductsInProductSet + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductsInProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductsInProductSetRequest): + request = product_search_service.ListProductsInProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_products_in_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductsInProductSetPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def import_product_sets(self, + request: Optional[Union[product_search_service.ImportProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + input_config: Optional[product_search_service.ImportProductSetsInputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1.ImportProductSetsGcsSource.csv_file_uri]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_import_product_sets(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.ImportProductSetsRequest, dict]): + The request object. Request message for the ``ImportProductSets`` method. + parent (str): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + input_config (google.cloud.vision_v1.types.ImportProductSetsInputConfig): + Required. The input content for the + list of requests. + + This corresponds to the ``input_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1.types.ImportProductSetsResponse` + Response message for the ImportProductSets method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, input_config]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ImportProductSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ImportProductSetsRequest): + request = product_search_service.ImportProductSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if input_config is not None: + request.input_config = input_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_product_sets] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + product_search_service.ImportProductSetsResponse, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + def purge_products(self, + request: Optional[Union[product_search_service.PurgeProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Asynchronous API to delete all Products in a ProductSet or all + Products that are in no ProductSet. + + If a Product is a member of the specified ProductSet in addition + to other ProductSets, the Product will still be deleted. + + It is recommended to not delete the specified ProductSet until + after this operation has completed. It is also recommended to + not add any of the Products involved in the batch delete to a + new ProductSet while this operation is running because those + Products may still end up deleted. + + It's not possible to undo the PurgeProducts operation. + Therefore, it is recommended to keep the csv files used in + ImportProductSets (if that was how you originally built the + Product Set) before starting PurgeProducts, in case you need to + re-import the data after deletion. + + If the plan is to purge all of the Products from a ProductSet + and then re-use the empty ProductSet to re-import new Products + into the empty ProductSet, you must wait until the PurgeProducts + operation has finished for that ProductSet. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1 + + def sample_purge_products(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.PurgeProductsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.purge_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1.types.PurgeProductsRequest, dict]): + The request object. Request message for the ``PurgeProducts`` method. + parent (str): + Required. The project and location in which the Products + should be deleted. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.PurgeProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.PurgeProductsRequest): + request = product_search_service.PurgeProductsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.purge_products] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ProductSearchClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductSearchClient", +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/pagers.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/pagers.py new file mode 100644 index 00000000..ea58be97 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/pagers.py @@ -0,0 +1,502 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator + +from google.cloud.vision_v1.types import product_search_service + + +class ListProductSetsPager: + """A pager for iterating through ``list_product_sets`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1.types.ListProductSetsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``product_sets`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProductSets`` requests and continue to iterate + through the ``product_sets`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1.types.ListProductSetsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductSetsResponse], + request: product_search_service.ListProductSetsRequest, + response: product_search_service.ListProductSetsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1.types.ListProductSetsRequest): + The initial request object. + response (google.cloud.vision_v1.types.ListProductSetsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductSetsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductSetsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.ProductSet]: + for page in self.pages: + yield from page.product_sets + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductSetsAsyncPager: + """A pager for iterating through ``list_product_sets`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1.types.ListProductSetsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``product_sets`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProductSets`` requests and continue to iterate + through the ``product_sets`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1.types.ListProductSetsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductSetsResponse]], + request: product_search_service.ListProductSetsRequest, + response: product_search_service.ListProductSetsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1.types.ListProductSetsRequest): + The initial request object. + response (google.cloud.vision_v1.types.ListProductSetsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductSetsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductSetsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.ProductSet]: + async def async_generator(): + async for page in self.pages: + for response in page.product_sets: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1.types.ListProductsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProducts`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1.types.ListProductsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductsResponse], + request: product_search_service.ListProductsRequest, + response: product_search_service.ListProductsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1.types.ListProductsRequest): + The initial request object. + response (google.cloud.vision_v1.types.ListProductsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.Product]: + for page in self.pages: + yield from page.products + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsAsyncPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1.types.ListProductsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProducts`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1.types.ListProductsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductsResponse]], + request: product_search_service.ListProductsRequest, + response: product_search_service.ListProductsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1.types.ListProductsRequest): + The initial request object. + response (google.cloud.vision_v1.types.ListProductsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.Product]: + async def async_generator(): + async for page in self.pages: + for response in page.products: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListReferenceImagesPager: + """A pager for iterating through ``list_reference_images`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1.types.ListReferenceImagesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``reference_images`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListReferenceImages`` requests and continue to iterate + through the ``reference_images`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1.types.ListReferenceImagesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListReferenceImagesResponse], + request: product_search_service.ListReferenceImagesRequest, + response: product_search_service.ListReferenceImagesResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1.types.ListReferenceImagesRequest): + The initial request object. + response (google.cloud.vision_v1.types.ListReferenceImagesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListReferenceImagesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListReferenceImagesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.ReferenceImage]: + for page in self.pages: + yield from page.reference_images + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListReferenceImagesAsyncPager: + """A pager for iterating through ``list_reference_images`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1.types.ListReferenceImagesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``reference_images`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListReferenceImages`` requests and continue to iterate + through the ``reference_images`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1.types.ListReferenceImagesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListReferenceImagesResponse]], + request: product_search_service.ListReferenceImagesRequest, + response: product_search_service.ListReferenceImagesResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1.types.ListReferenceImagesRequest): + The initial request object. + response (google.cloud.vision_v1.types.ListReferenceImagesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListReferenceImagesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListReferenceImagesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.ReferenceImage]: + async def async_generator(): + async for page in self.pages: + for response in page.reference_images: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsInProductSetPager: + """A pager for iterating through ``list_products_in_product_set`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1.types.ListProductsInProductSetResponse` object, and + provides an ``__iter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProductsInProductSet`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1.types.ListProductsInProductSetResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductsInProductSetResponse], + request: product_search_service.ListProductsInProductSetRequest, + response: product_search_service.ListProductsInProductSetResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1.types.ListProductsInProductSetRequest): + The initial request object. + response (google.cloud.vision_v1.types.ListProductsInProductSetResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsInProductSetRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductsInProductSetResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.Product]: + for page in self.pages: + yield from page.products + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsInProductSetAsyncPager: + """A pager for iterating through ``list_products_in_product_set`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1.types.ListProductsInProductSetResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProductsInProductSet`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1.types.ListProductsInProductSetResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductsInProductSetResponse]], + request: product_search_service.ListProductsInProductSetRequest, + response: product_search_service.ListProductsInProductSetResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1.types.ListProductsInProductSetRequest): + The initial request object. + response (google.cloud.vision_v1.types.ListProductsInProductSetResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsInProductSetRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductsInProductSetResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.Product]: + async def async_generator(): + async for page in self.pages: + for response in page.products: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/__init__.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/__init__.py new file mode 100644 index 00000000..eb2b97bb --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +from typing import Dict, Type + +from .base import ProductSearchTransport +from .grpc import ProductSearchGrpcTransport +from .grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .rest import ProductSearchRestTransport +from .rest import ProductSearchRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ProductSearchTransport]] +_transport_registry['grpc'] = ProductSearchGrpcTransport +_transport_registry['grpc_asyncio'] = ProductSearchGrpcAsyncIOTransport +_transport_registry['rest'] = ProductSearchRestTransport + +__all__ = ( + 'ProductSearchTransport', + 'ProductSearchGrpcTransport', + 'ProductSearchGrpcAsyncIOTransport', + 'ProductSearchRestTransport', + 'ProductSearchRestInterceptor', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/base.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/base.py new file mode 100644 index 00000000..eac707b3 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/base.py @@ -0,0 +1,532 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.vision_v1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.vision_v1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ProductSearchTransport(abc.ABC): + """Abstract transport class for ProductSearch.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', + ) + + DEFAULT_HOST: str = 'vision.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience(api_audience if api_audience else host) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_product_set: gapic_v1.method.wrap_method( + self.create_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_product_sets: gapic_v1.method.wrap_method( + self.list_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_product_set: gapic_v1.method.wrap_method( + self.get_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.update_product_set: gapic_v1.method.wrap_method( + self.update_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_product_set: gapic_v1.method.wrap_method( + self.delete_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.create_product: gapic_v1.method.wrap_method( + self.create_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_products: gapic_v1.method.wrap_method( + self.list_products, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_product: gapic_v1.method.wrap_method( + self.get_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.update_product: gapic_v1.method.wrap_method( + self.update_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_product: gapic_v1.method.wrap_method( + self.delete_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.create_reference_image: gapic_v1.method.wrap_method( + self.create_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_reference_image: gapic_v1.method.wrap_method( + self.delete_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_reference_images: gapic_v1.method.wrap_method( + self.list_reference_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_reference_image: gapic_v1.method.wrap_method( + self.get_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.add_product_to_product_set: gapic_v1.method.wrap_method( + self.add_product_to_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.remove_product_from_product_set: gapic_v1.method.wrap_method( + self.remove_product_from_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_products_in_product_set: gapic_v1.method.wrap_method( + self.list_products_in_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.import_product_sets: gapic_v1.method.wrap_method( + self.import_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.purge_products: gapic_v1.method.wrap_method( + self.purge_products, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + Union[ + product_search_service.ListProductSetsResponse, + Awaitable[product_search_service.ListProductSetsResponse] + ]]: + raise NotImplementedError() + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + Union[ + product_search_service.ListProductsResponse, + Awaitable[product_search_service.ListProductsResponse] + ]]: + raise NotImplementedError() + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + Union[ + product_search_service.ReferenceImage, + Awaitable[product_search_service.ReferenceImage] + ]]: + raise NotImplementedError() + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + Union[ + product_search_service.ListReferenceImagesResponse, + Awaitable[product_search_service.ListReferenceImagesResponse] + ]]: + raise NotImplementedError() + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + Union[ + product_search_service.ReferenceImage, + Awaitable[product_search_service.ReferenceImage] + ]]: + raise NotImplementedError() + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + Union[ + product_search_service.ListProductsInProductSetResponse, + Awaitable[product_search_service.ListProductsInProductSetResponse] + ]]: + raise NotImplementedError() + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def purge_products(self) -> Callable[ + [product_search_service.PurgeProductsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ProductSearchTransport', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/grpc.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/grpc.py new file mode 100644 index 00000000..7da7f438 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/grpc.py @@ -0,0 +1,924 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.vision_v1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO + + +class ProductSearchGrpcTransport(ProductSearchTransport): + """gRPC backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1.ProductSet] resources, named + ``projects/*/locations/*/productSets/*``, which acts as a way to + put different products into groups to limit identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1.Product] has a collection + of [ReferenceImage][google.cloud.vision.v1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the create product set method over gRPC. + + Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + Returns: + Callable[[~.CreateProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product_set' not in self._stubs: + self._stubs['create_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/CreateProductSet', + request_serializer=product_search_service.CreateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['create_product_set'] + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + product_search_service.ListProductSetsResponse]: + r"""Return a callable for the list product sets method over gRPC. + + Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + Returns: + Callable[[~.ListProductSetsRequest], + ~.ListProductSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_product_sets' not in self._stubs: + self._stubs['list_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ListProductSets', + request_serializer=product_search_service.ListProductSetsRequest.serialize, + response_deserializer=product_search_service.ListProductSetsResponse.deserialize, + ) + return self._stubs['list_product_sets'] + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the get product set method over gRPC. + + Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + Returns: + Callable[[~.GetProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product_set' not in self._stubs: + self._stubs['get_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/GetProductSet', + request_serializer=product_search_service.GetProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['get_product_set'] + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the update product set method over gRPC. + + Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + Returns: + Callable[[~.UpdateProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product_set' not in self._stubs: + self._stubs['update_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/UpdateProductSet', + request_serializer=product_search_service.UpdateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['update_product_set'] + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product set method over gRPC. + + Permanently deletes a ProductSet. Products and + ReferenceImages in the ProductSet are not deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + Returns: + Callable[[~.DeleteProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product_set' not in self._stubs: + self._stubs['delete_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/DeleteProductSet', + request_serializer=product_search_service.DeleteProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product_set'] + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + product_search_service.Product]: + r"""Return a callable for the create product method over gRPC. + + Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + Returns: + Callable[[~.CreateProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product' not in self._stubs: + self._stubs['create_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/CreateProduct', + request_serializer=product_search_service.CreateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + product_search_service.ListProductsResponse]: + r"""Return a callable for the list products method over gRPC. + + Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsRequest], + ~.ListProductsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products' not in self._stubs: + self._stubs['list_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ListProducts', + request_serializer=product_search_service.ListProductsRequest.serialize, + response_deserializer=product_search_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + product_search_service.Product]: + r"""Return a callable for the get product method over gRPC. + + Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + Returns: + Callable[[~.GetProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product' not in self._stubs: + self._stubs['get_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/GetProduct', + request_serializer=product_search_service.GetProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + product_search_service.Product]: + r"""Return a callable for the update product method over gRPC. + + Makes changes to a Product resource. Only the ``display_name``, + ``description``, and ``labels`` fields can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + Returns: + Callable[[~.UpdateProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product' not in self._stubs: + self._stubs['update_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/UpdateProduct', + request_serializer=product_search_service.UpdateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product method over gRPC. + + Permanently deletes a product and its reference + images. + Metadata of the product and all its images will be + deleted right away, but search queries against + ProductSets containing the product may still work until + all related caches are refreshed. + + Returns: + Callable[[~.DeleteProductRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product' not in self._stubs: + self._stubs['delete_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/DeleteProduct', + request_serializer=product_search_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + product_search_service.ReferenceImage]: + r"""Return a callable for the create reference image method over gRPC. + + Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + Returns: + Callable[[~.CreateReferenceImageRequest], + ~.ReferenceImage]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_reference_image' not in self._stubs: + self._stubs['create_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/CreateReferenceImage', + request_serializer=product_search_service.CreateReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['create_reference_image'] + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete reference image method over gRPC. + + Permanently deletes a reference image. + + The image metadata will be deleted right away, but + search queries against ProductSets containing the image + may still work until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + Returns: + Callable[[~.DeleteReferenceImageRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_reference_image' not in self._stubs: + self._stubs['delete_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/DeleteReferenceImage', + request_serializer=product_search_service.DeleteReferenceImageRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_reference_image'] + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + product_search_service.ListReferenceImagesResponse]: + r"""Return a callable for the list reference images method over gRPC. + + Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + Returns: + Callable[[~.ListReferenceImagesRequest], + ~.ListReferenceImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_reference_images' not in self._stubs: + self._stubs['list_reference_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ListReferenceImages', + request_serializer=product_search_service.ListReferenceImagesRequest.serialize, + response_deserializer=product_search_service.ListReferenceImagesResponse.deserialize, + ) + return self._stubs['list_reference_images'] + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + product_search_service.ReferenceImage]: + r"""Return a callable for the get reference image method over gRPC. + + Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + Returns: + Callable[[~.GetReferenceImageRequest], + ~.ReferenceImage]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_reference_image' not in self._stubs: + self._stubs['get_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/GetReferenceImage', + request_serializer=product_search_service.GetReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['get_reference_image'] + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the add product to product set method over gRPC. + + Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + Returns: + Callable[[~.AddProductToProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'add_product_to_product_set' not in self._stubs: + self._stubs['add_product_to_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/AddProductToProductSet', + request_serializer=product_search_service.AddProductToProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['add_product_to_product_set'] + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the remove product from product + set method over gRPC. + + Removes a Product from the specified ProductSet. + + Returns: + Callable[[~.RemoveProductFromProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'remove_product_from_product_set' not in self._stubs: + self._stubs['remove_product_from_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/RemoveProductFromProductSet', + request_serializer=product_search_service.RemoveProductFromProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['remove_product_from_product_set'] + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + product_search_service.ListProductsInProductSetResponse]: + r"""Return a callable for the list products in product set method over gRPC. + + Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsInProductSetRequest], + ~.ListProductsInProductSetResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products_in_product_set' not in self._stubs: + self._stubs['list_products_in_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ListProductsInProductSet', + request_serializer=product_search_service.ListProductsInProductSetRequest.serialize, + response_deserializer=product_search_service.ListProductsInProductSetResponse.deserialize, + ) + return self._stubs['list_products_in_product_set'] + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import product sets method over gRPC. + + Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1.ImportProductSetsGcsSource.csv_file_uri]. + + Returns: + Callable[[~.ImportProductSetsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'import_product_sets' not in self._stubs: + self._stubs['import_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ImportProductSets', + request_serializer=product_search_service.ImportProductSetsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_product_sets'] + + @property + def purge_products(self) -> Callable[ + [product_search_service.PurgeProductsRequest], + operations_pb2.Operation]: + r"""Return a callable for the purge products method over gRPC. + + Asynchronous API to delete all Products in a ProductSet or all + Products that are in no ProductSet. + + If a Product is a member of the specified ProductSet in addition + to other ProductSets, the Product will still be deleted. + + It is recommended to not delete the specified ProductSet until + after this operation has completed. It is also recommended to + not add any of the Products involved in the batch delete to a + new ProductSet while this operation is running because those + Products may still end up deleted. + + It's not possible to undo the PurgeProducts operation. + Therefore, it is recommended to keep the csv files used in + ImportProductSets (if that was how you originally built the + Product Set) before starting PurgeProducts, in case you need to + re-import the data after deletion. + + If the plan is to purge all of the Products from a ProductSet + and then re-use the empty ProductSet to re-import new Products + into the empty ProductSet, you must wait until the PurgeProducts + operation has finished for that ProductSet. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) + + Returns: + Callable[[~.PurgeProductsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'purge_products' not in self._stubs: + self._stubs['purge_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/PurgeProducts', + request_serializer=product_search_service.PurgeProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_products'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ProductSearchGrpcTransport', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/grpc_asyncio.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/grpc_asyncio.py new file mode 100644 index 00000000..2a5d9dc1 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/grpc_asyncio.py @@ -0,0 +1,923 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.vision_v1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .grpc import ProductSearchGrpcTransport + + +class ProductSearchGrpcAsyncIOTransport(ProductSearchTransport): + """gRPC AsyncIO backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1.ProductSet] resources, named + ``projects/*/locations/*/productSets/*``, which acts as a way to + put different products into groups to limit identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1.Product] has a collection + of [ReferenceImage][google.cloud.vision.v1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the create product set method over gRPC. + + Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + Returns: + Callable[[~.CreateProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product_set' not in self._stubs: + self._stubs['create_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/CreateProductSet', + request_serializer=product_search_service.CreateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['create_product_set'] + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + Awaitable[product_search_service.ListProductSetsResponse]]: + r"""Return a callable for the list product sets method over gRPC. + + Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + Returns: + Callable[[~.ListProductSetsRequest], + Awaitable[~.ListProductSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_product_sets' not in self._stubs: + self._stubs['list_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ListProductSets', + request_serializer=product_search_service.ListProductSetsRequest.serialize, + response_deserializer=product_search_service.ListProductSetsResponse.deserialize, + ) + return self._stubs['list_product_sets'] + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the get product set method over gRPC. + + Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + Returns: + Callable[[~.GetProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product_set' not in self._stubs: + self._stubs['get_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/GetProductSet', + request_serializer=product_search_service.GetProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['get_product_set'] + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the update product set method over gRPC. + + Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + Returns: + Callable[[~.UpdateProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product_set' not in self._stubs: + self._stubs['update_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/UpdateProductSet', + request_serializer=product_search_service.UpdateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['update_product_set'] + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product set method over gRPC. + + Permanently deletes a ProductSet. Products and + ReferenceImages in the ProductSet are not deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + Returns: + Callable[[~.DeleteProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product_set' not in self._stubs: + self._stubs['delete_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/DeleteProductSet', + request_serializer=product_search_service.DeleteProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product_set'] + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the create product method over gRPC. + + Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + Returns: + Callable[[~.CreateProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product' not in self._stubs: + self._stubs['create_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/CreateProduct', + request_serializer=product_search_service.CreateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + Awaitable[product_search_service.ListProductsResponse]]: + r"""Return a callable for the list products method over gRPC. + + Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsRequest], + Awaitable[~.ListProductsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products' not in self._stubs: + self._stubs['list_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ListProducts', + request_serializer=product_search_service.ListProductsRequest.serialize, + response_deserializer=product_search_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the get product method over gRPC. + + Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + Returns: + Callable[[~.GetProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product' not in self._stubs: + self._stubs['get_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/GetProduct', + request_serializer=product_search_service.GetProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the update product method over gRPC. + + Makes changes to a Product resource. Only the ``display_name``, + ``description``, and ``labels`` fields can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + Returns: + Callable[[~.UpdateProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product' not in self._stubs: + self._stubs['update_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/UpdateProduct', + request_serializer=product_search_service.UpdateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product method over gRPC. + + Permanently deletes a product and its reference + images. + Metadata of the product and all its images will be + deleted right away, but search queries against + ProductSets containing the product may still work until + all related caches are refreshed. + + Returns: + Callable[[~.DeleteProductRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product' not in self._stubs: + self._stubs['delete_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/DeleteProduct', + request_serializer=product_search_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + Awaitable[product_search_service.ReferenceImage]]: + r"""Return a callable for the create reference image method over gRPC. + + Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + Returns: + Callable[[~.CreateReferenceImageRequest], + Awaitable[~.ReferenceImage]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_reference_image' not in self._stubs: + self._stubs['create_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/CreateReferenceImage', + request_serializer=product_search_service.CreateReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['create_reference_image'] + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete reference image method over gRPC. + + Permanently deletes a reference image. + + The image metadata will be deleted right away, but + search queries against ProductSets containing the image + may still work until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + Returns: + Callable[[~.DeleteReferenceImageRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_reference_image' not in self._stubs: + self._stubs['delete_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/DeleteReferenceImage', + request_serializer=product_search_service.DeleteReferenceImageRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_reference_image'] + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + Awaitable[product_search_service.ListReferenceImagesResponse]]: + r"""Return a callable for the list reference images method over gRPC. + + Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + Returns: + Callable[[~.ListReferenceImagesRequest], + Awaitable[~.ListReferenceImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_reference_images' not in self._stubs: + self._stubs['list_reference_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ListReferenceImages', + request_serializer=product_search_service.ListReferenceImagesRequest.serialize, + response_deserializer=product_search_service.ListReferenceImagesResponse.deserialize, + ) + return self._stubs['list_reference_images'] + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + Awaitable[product_search_service.ReferenceImage]]: + r"""Return a callable for the get reference image method over gRPC. + + Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + Returns: + Callable[[~.GetReferenceImageRequest], + Awaitable[~.ReferenceImage]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_reference_image' not in self._stubs: + self._stubs['get_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/GetReferenceImage', + request_serializer=product_search_service.GetReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['get_reference_image'] + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the add product to product set method over gRPC. + + Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + Returns: + Callable[[~.AddProductToProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'add_product_to_product_set' not in self._stubs: + self._stubs['add_product_to_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/AddProductToProductSet', + request_serializer=product_search_service.AddProductToProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['add_product_to_product_set'] + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the remove product from product + set method over gRPC. + + Removes a Product from the specified ProductSet. + + Returns: + Callable[[~.RemoveProductFromProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'remove_product_from_product_set' not in self._stubs: + self._stubs['remove_product_from_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/RemoveProductFromProductSet', + request_serializer=product_search_service.RemoveProductFromProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['remove_product_from_product_set'] + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + Awaitable[product_search_service.ListProductsInProductSetResponse]]: + r"""Return a callable for the list products in product set method over gRPC. + + Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsInProductSetRequest], + Awaitable[~.ListProductsInProductSetResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products_in_product_set' not in self._stubs: + self._stubs['list_products_in_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ListProductsInProductSet', + request_serializer=product_search_service.ListProductsInProductSetRequest.serialize, + response_deserializer=product_search_service.ListProductsInProductSetResponse.deserialize, + ) + return self._stubs['list_products_in_product_set'] + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import product sets method over gRPC. + + Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1.ImportProductSetsGcsSource.csv_file_uri]. + + Returns: + Callable[[~.ImportProductSetsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'import_product_sets' not in self._stubs: + self._stubs['import_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/ImportProductSets', + request_serializer=product_search_service.ImportProductSetsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_product_sets'] + + @property + def purge_products(self) -> Callable[ + [product_search_service.PurgeProductsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the purge products method over gRPC. + + Asynchronous API to delete all Products in a ProductSet or all + Products that are in no ProductSet. + + If a Product is a member of the specified ProductSet in addition + to other ProductSets, the Product will still be deleted. + + It is recommended to not delete the specified ProductSet until + after this operation has completed. It is also recommended to + not add any of the Products involved in the batch delete to a + new ProductSet while this operation is running because those + Products may still end up deleted. + + It's not possible to undo the PurgeProducts operation. + Therefore, it is recommended to keep the csv files used in + ImportProductSets (if that was how you originally built the + Product Set) before starting PurgeProducts, in case you need to + re-import the data after deletion. + + If the plan is to purge all of the Products from a ProductSet + and then re-use the empty ProductSet to re-import new Products + into the empty ProductSet, you must wait until the PurgeProducts + operation has finished for that ProductSet. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) + + Returns: + Callable[[~.PurgeProductsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'purge_products' not in self._stubs: + self._stubs['purge_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1.ProductSearch/PurgeProducts', + request_serializer=product_search_service.PurgeProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_products'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ProductSearchGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/rest.py b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/rest.py new file mode 100644 index 00000000..e532321e --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/services/product_search/transports/rest.py @@ -0,0 +1,2322 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.auth.transport.requests import AuthorizedSession # type: ignore +import json # type: ignore +import grpc # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.api_core import rest_helpers +from google.api_core import rest_streaming +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from google.api_core import operations_v1 +from requests import __version__ as requests_version +import dataclasses +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.cloud.vision_v1.types import product_search_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ProductSearchRestInterceptor: + """Interceptor for ProductSearch. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ProductSearchRestTransport. + + .. code-block:: python + class MyCustomProductSearchInterceptor(ProductSearchRestInterceptor): + def pre_add_product_to_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_create_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_reference_image(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_reference_image(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_product_sets(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_product_sets(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_products(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_products(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_product_sets(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_product_sets(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_products_in_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_products_in_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_reference_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_reference_images(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_purge_products(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_purge_products(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_product_from_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_update_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ProductSearchRestTransport(interceptor=MyCustomProductSearchInterceptor()) + client = ProductSearchClient(transport=transport) + + + """ + def pre_add_product_to_product_set(self, request: product_search_service.AddProductToProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.AddProductToProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_product_to_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_create_product(self, request: product_search_service.CreateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for create_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_create_product_set(self, request: product_search_service.CreateProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for create_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_create_reference_image(self, request: product_search_service.CreateReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_reference_image(self, response: product_search_service.ReferenceImage) -> product_search_service.ReferenceImage: + """Post-rpc interceptor for create_reference_image + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_delete_product(self, request: product_search_service.DeleteProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_delete_product_set(self, request: product_search_service.DeleteProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_delete_reference_image(self, request: product_search_service.DeleteReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_get_product(self, request: product_search_service.GetProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for get_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_get_product_set(self, request: product_search_service.GetProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for get_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_get_reference_image(self, request: product_search_service.GetReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_reference_image(self, response: product_search_service.ReferenceImage) -> product_search_service.ReferenceImage: + """Post-rpc interceptor for get_reference_image + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_import_product_sets(self, request: product_search_service.ImportProductSetsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ImportProductSetsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_product_sets + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_import_product_sets(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_product_sets + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_products(self, request: product_search_service.ListProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_products + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_products(self, response: product_search_service.ListProductsResponse) -> product_search_service.ListProductsResponse: + """Post-rpc interceptor for list_products + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_product_sets(self, request: product_search_service.ListProductSetsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductSetsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_product_sets + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_product_sets(self, response: product_search_service.ListProductSetsResponse) -> product_search_service.ListProductSetsResponse: + """Post-rpc interceptor for list_product_sets + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_products_in_product_set(self, request: product_search_service.ListProductsInProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductsInProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_products_in_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_products_in_product_set(self, response: product_search_service.ListProductsInProductSetResponse) -> product_search_service.ListProductsInProductSetResponse: + """Post-rpc interceptor for list_products_in_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_reference_images(self, request: product_search_service.ListReferenceImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListReferenceImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_reference_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_reference_images(self, response: product_search_service.ListReferenceImagesResponse) -> product_search_service.ListReferenceImagesResponse: + """Post-rpc interceptor for list_reference_images + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_purge_products(self, request: product_search_service.PurgeProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.PurgeProductsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for purge_products + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_purge_products(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for purge_products + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_remove_product_from_product_set(self, request: product_search_service.RemoveProductFromProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.RemoveProductFromProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_product_from_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_update_product(self, request: product_search_service.UpdateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.UpdateProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_update_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for update_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_update_product_set(self, request: product_search_service.UpdateProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.UpdateProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_update_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for update_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ProductSearchRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ProductSearchRestInterceptor + + +class ProductSearchRestTransport(ProductSearchTransport): + """REST backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1.ProductSet] resources, named + ``projects/*/locations/*/productSets/*``, which acts as a way to + put different products into groups to limit identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1.Product] has a collection + of [ReferenceImage][google.cloud.vision.v1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[ + ], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + interceptor: Optional[ProductSearchRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError(f"Unexpected hostname structure: {host}") # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ProductSearchRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + 'google.longrunning.Operations.GetOperation': [ + { + 'method': 'get', + 'uri': '/v1/{name=projects/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v1/{name=operations/*}', + }, + { + 'method': 'get', + 'uri': '/v1/{name=locations/*/operations/*}', + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AddProductToProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("AddProductToProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.AddProductToProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the add product to product + set method over HTTP. + + Args: + request (~.product_search_service.AddProductToProductSetRequest): + The request object. Request message for the ``AddProductToProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{name=projects/*/locations/*/productSets/*}:addProduct', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_product_to_product_set(request, metadata) + pb_request = product_search_service.AddProductToProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _CreateProduct(ProductSearchRestStub): + def __hash__(self): + return hash("CreateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the create product method over HTTP. + + Args: + request (~.product_search_service.CreateProductRequest): + The request object. Request message for the ``CreateProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/products', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_create_product(request, metadata) + pb_request = product_search_service.CreateProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product(resp) + return resp + + class _CreateProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("CreateProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the create product set method over HTTP. + + Args: + request (~.product_search_service.CreateProductSetRequest): + The request object. Request message for the ``CreateProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/productSets', + 'body': 'product_set', + }, + ] + request, metadata = self._interceptor.pre_create_product_set(request, metadata) + pb_request = product_search_service.CreateProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product_set(resp) + return resp + + class _CreateReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("CreateReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ReferenceImage: + r"""Call the create reference image method over HTTP. + + Args: + request (~.product_search_service.CreateReferenceImageRequest): + The request object. Request message for the ``CreateReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ReferenceImage: + A ``ReferenceImage`` represents a product image and its + associated metadata, such as bounding boxes. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*/products/*}/referenceImages', + 'body': 'reference_image', + }, + ] + request, metadata = self._interceptor.pre_create_reference_image(request, metadata) + pb_request = product_search_service.CreateReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ReferenceImage() + pb_resp = product_search_service.ReferenceImage.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_reference_image(resp) + return resp + + class _DeleteProduct(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete product method over HTTP. + + Args: + request (~.product_search_service.DeleteProductRequest): + The request object. Request message for the ``DeleteProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1/{name=projects/*/locations/*/products/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_product(request, metadata) + pb_request = product_search_service.DeleteProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete product set method over HTTP. + + Args: + request (~.product_search_service.DeleteProductSetRequest): + The request object. Request message for the ``DeleteProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1/{name=projects/*/locations/*/productSets/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_product_set(request, metadata) + pb_request = product_search_service.DeleteProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete reference image method over HTTP. + + Args: + request (~.product_search_service.DeleteReferenceImageRequest): + The request object. Request message for the ``DeleteReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1/{name=projects/*/locations/*/products/*/referenceImages/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_reference_image(request, metadata) + pb_request = product_search_service.DeleteReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _GetProduct(ProductSearchRestStub): + def __hash__(self): + return hash("GetProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the get product method over HTTP. + + Args: + request (~.product_search_service.GetProductRequest): + The request object. Request message for the ``GetProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/products/*}', + }, + ] + request, metadata = self._interceptor.pre_get_product(request, metadata) + pb_request = product_search_service.GetProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product(resp) + return resp + + class _GetProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("GetProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the get product set method over HTTP. + + Args: + request (~.product_search_service.GetProductSetRequest): + The request object. Request message for the ``GetProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/productSets/*}', + }, + ] + request, metadata = self._interceptor.pre_get_product_set(request, metadata) + pb_request = product_search_service.GetProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product_set(resp) + return resp + + class _GetReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("GetReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ReferenceImage: + r"""Call the get reference image method over HTTP. + + Args: + request (~.product_search_service.GetReferenceImageRequest): + The request object. Request message for the ``GetReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ReferenceImage: + A ``ReferenceImage`` represents a product image and its + associated metadata, such as bounding boxes. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/products/*/referenceImages/*}', + }, + ] + request, metadata = self._interceptor.pre_get_reference_image(request, metadata) + pb_request = product_search_service.GetReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ReferenceImage() + pb_resp = product_search_service.ReferenceImage.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_reference_image(resp) + return resp + + class _ImportProductSets(ProductSearchRestStub): + def __hash__(self): + return hash("ImportProductSets") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ImportProductSetsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import product sets method over HTTP. + + Args: + request (~.product_search_service.ImportProductSetsRequest): + The request object. Request message for the ``ImportProductSets`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/productSets:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_product_sets(request, metadata) + pb_request = product_search_service.ImportProductSetsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_import_product_sets(resp) + return resp + + class _ListProducts(ProductSearchRestStub): + def __hash__(self): + return hash("ListProducts") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductsResponse: + r"""Call the list products method over HTTP. + + Args: + request (~.product_search_service.ListProductsRequest): + The request object. Request message for the ``ListProducts`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductsResponse: + Response message for the ``ListProducts`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{parent=projects/*/locations/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products(request, metadata) + pb_request = product_search_service.ListProductsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductsResponse() + pb_resp = product_search_service.ListProductsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_products(resp) + return resp + + class _ListProductSets(ProductSearchRestStub): + def __hash__(self): + return hash("ListProductSets") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductSetsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductSetsResponse: + r"""Call the list product sets method over HTTP. + + Args: + request (~.product_search_service.ListProductSetsRequest): + The request object. Request message for the ``ListProductSets`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductSetsResponse: + Response message for the ``ListProductSets`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{parent=projects/*/locations/*}/productSets', + }, + ] + request, metadata = self._interceptor.pre_list_product_sets(request, metadata) + pb_request = product_search_service.ListProductSetsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductSetsResponse() + pb_resp = product_search_service.ListProductSetsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_product_sets(resp) + return resp + + class _ListProductsInProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("ListProductsInProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductsInProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductsInProductSetResponse: + r"""Call the list products in product + set method over HTTP. + + Args: + request (~.product_search_service.ListProductsInProductSetRequest): + The request object. Request message for the ``ListProductsInProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductsInProductSetResponse: + Response message for the ``ListProductsInProductSet`` + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/productSets/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products_in_product_set(request, metadata) + pb_request = product_search_service.ListProductsInProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductsInProductSetResponse() + pb_resp = product_search_service.ListProductsInProductSetResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_products_in_product_set(resp) + return resp + + class _ListReferenceImages(ProductSearchRestStub): + def __hash__(self): + return hash("ListReferenceImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListReferenceImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListReferenceImagesResponse: + r"""Call the list reference images method over HTTP. + + Args: + request (~.product_search_service.ListReferenceImagesRequest): + The request object. Request message for the ``ListReferenceImages`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListReferenceImagesResponse: + Response message for the ``ListReferenceImages`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{parent=projects/*/locations/*/products/*}/referenceImages', + }, + ] + request, metadata = self._interceptor.pre_list_reference_images(request, metadata) + pb_request = product_search_service.ListReferenceImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListReferenceImagesResponse() + pb_resp = product_search_service.ListReferenceImagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_reference_images(resp) + return resp + + class _PurgeProducts(ProductSearchRestStub): + def __hash__(self): + return hash("PurgeProducts") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.PurgeProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the purge products method over HTTP. + + Args: + request (~.product_search_service.PurgeProductsRequest): + The request object. Request message for the ``PurgeProducts`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/products:purge', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_purge_products(request, metadata) + pb_request = product_search_service.PurgeProductsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_purge_products(resp) + return resp + + class _RemoveProductFromProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("RemoveProductFromProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.RemoveProductFromProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the remove product from + product set method over HTTP. + + Args: + request (~.product_search_service.RemoveProductFromProductSetRequest): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{name=projects/*/locations/*/productSets/*}:removeProduct', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_product_from_product_set(request, metadata) + pb_request = product_search_service.RemoveProductFromProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _UpdateProduct(ProductSearchRestStub): + def __hash__(self): + return hash("UpdateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.UpdateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the update product method over HTTP. + + Args: + request (~.product_search_service.UpdateProductRequest): + The request object. Request message for the ``UpdateProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v1/{product.name=projects/*/locations/*/products/*}', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_update_product(request, metadata) + pb_request = product_search_service.UpdateProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product(resp) + return resp + + class _UpdateProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("UpdateProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.UpdateProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the update product set method over HTTP. + + Args: + request (~.product_search_service.UpdateProductSetRequest): + The request object. Request message for the ``UpdateProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v1/{product_set.name=projects/*/locations/*/productSets/*}', + 'body': 'product_set', + }, + ] + request, metadata = self._interceptor.pre_update_product_set(request, metadata) + pb_request = product_search_service.UpdateProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product_set(resp) + return resp + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AddProductToProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + product_search_service.ReferenceImage]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + product_search_service.ReferenceImage]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ImportProductSets(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + product_search_service.ListProductsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProducts(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + product_search_service.ListProductSetsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProductSets(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + product_search_service.ListProductsInProductSetResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProductsInProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + product_search_service.ListReferenceImagesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListReferenceImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def purge_products(self) -> Callable[ + [product_search_service.PurgeProductsRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._PurgeProducts(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._RemoveProductFromProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ProductSearchRestTransport', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/types/__init__.py b/owl-bot-staging/v1/google/cloud/vision_v1/types/__init__.py new file mode 100644 index 00000000..5e685bd5 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/types/__init__.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .geometry import ( + BoundingPoly, + NormalizedVertex, + Position, + Vertex, +) +from .image_annotator import ( + AnnotateFileRequest, + AnnotateFileResponse, + AnnotateImageRequest, + AnnotateImageResponse, + AsyncAnnotateFileRequest, + AsyncAnnotateFileResponse, + AsyncBatchAnnotateFilesRequest, + AsyncBatchAnnotateFilesResponse, + AsyncBatchAnnotateImagesRequest, + AsyncBatchAnnotateImagesResponse, + BatchAnnotateFilesRequest, + BatchAnnotateFilesResponse, + BatchAnnotateImagesRequest, + BatchAnnotateImagesResponse, + ColorInfo, + CropHint, + CropHintsAnnotation, + CropHintsParams, + DominantColorsAnnotation, + EntityAnnotation, + FaceAnnotation, + Feature, + GcsDestination, + GcsSource, + Image, + ImageAnnotationContext, + ImageContext, + ImageProperties, + ImageSource, + InputConfig, + LatLongRect, + LocalizedObjectAnnotation, + LocationInfo, + OperationMetadata, + OutputConfig, + Property, + SafeSearchAnnotation, + TextDetectionParams, + WebDetectionParams, + Likelihood, +) +from .product_search import ( + ProductSearchParams, + ProductSearchResults, +) +from .product_search_service import ( + AddProductToProductSetRequest, + BatchOperationMetadata, + CreateProductRequest, + CreateProductSetRequest, + CreateReferenceImageRequest, + DeleteProductRequest, + DeleteProductSetRequest, + DeleteReferenceImageRequest, + GetProductRequest, + GetProductSetRequest, + GetReferenceImageRequest, + ImportProductSetsGcsSource, + ImportProductSetsInputConfig, + ImportProductSetsRequest, + ImportProductSetsResponse, + ListProductSetsRequest, + ListProductSetsResponse, + ListProductsInProductSetRequest, + ListProductsInProductSetResponse, + ListProductsRequest, + ListProductsResponse, + ListReferenceImagesRequest, + ListReferenceImagesResponse, + Product, + ProductSet, + ProductSetPurgeConfig, + PurgeProductsRequest, + ReferenceImage, + RemoveProductFromProductSetRequest, + UpdateProductRequest, + UpdateProductSetRequest, +) +from .text_annotation import ( + Block, + Page, + Paragraph, + Symbol, + TextAnnotation, + Word, +) +from .web_detection import ( + WebDetection, +) + +__all__ = ( + 'BoundingPoly', + 'NormalizedVertex', + 'Position', + 'Vertex', + 'AnnotateFileRequest', + 'AnnotateFileResponse', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'AsyncBatchAnnotateImagesRequest', + 'AsyncBatchAnnotateImagesResponse', + 'BatchAnnotateFilesRequest', + 'BatchAnnotateFilesResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'GcsDestination', + 'GcsSource', + 'Image', + 'ImageAnnotationContext', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'InputConfig', + 'LatLongRect', + 'LocalizedObjectAnnotation', + 'LocationInfo', + 'OperationMetadata', + 'OutputConfig', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'ProductSearchParams', + 'ProductSearchResults', + 'AddProductToProductSetRequest', + 'BatchOperationMetadata', + 'CreateProductRequest', + 'CreateProductSetRequest', + 'CreateReferenceImageRequest', + 'DeleteProductRequest', + 'DeleteProductSetRequest', + 'DeleteReferenceImageRequest', + 'GetProductRequest', + 'GetProductSetRequest', + 'GetReferenceImageRequest', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ListProductsRequest', + 'ListProductsResponse', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'Product', + 'ProductSet', + 'ProductSetPurgeConfig', + 'PurgeProductsRequest', + 'ReferenceImage', + 'RemoveProductFromProductSetRequest', + 'UpdateProductRequest', + 'UpdateProductSetRequest', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/types/geometry.py b/owl-bot-staging/v1/google/cloud/vision_v1/types/geometry.py new file mode 100644 index 00000000..49c2ea4b --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/types/geometry.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1', + manifest={ + 'Vertex', + 'NormalizedVertex', + 'BoundingPoly', + 'Position', + }, +) + + +class Vertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the vertex coordinates are in the same scale as the + original image. + + Attributes: + x (int): + X coordinate. + y (int): + Y coordinate. + """ + + x: int = proto.Field( + proto.INT32, + number=1, + ) + y: int = proto.Field( + proto.INT32, + number=2, + ) + + +class NormalizedVertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the normalized vertex coordinates are relative to the + original image and range from 0 to 1. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + + +class BoundingPoly(proto.Message): + r"""A bounding polygon for the detected image annotation. + + Attributes: + vertices (MutableSequence[google.cloud.vision_v1.types.Vertex]): + The bounding polygon vertices. + normalized_vertices (MutableSequence[google.cloud.vision_v1.types.NormalizedVertex]): + The bounding polygon normalized vertices. + """ + + vertices: MutableSequence['Vertex'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Vertex', + ) + normalized_vertices: MutableSequence['NormalizedVertex'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='NormalizedVertex', + ) + + +class Position(proto.Message): + r"""A 3D position in the image, used primarily for Face detection + landmarks. A valid Position must have both x and y coordinates. + The position coordinates are in the same scale as the original + image. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + z (float): + Z coordinate (or depth). + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + z: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/types/image_annotator.py b/owl-bot-staging/v1/google/cloud/vision_v1/types/image_annotator.py new file mode 100644 index 00000000..30d8e49a --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/types/image_annotator.py @@ -0,0 +1,1725 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1.types import geometry +from google.cloud.vision_v1.types import product_search +from google.cloud.vision_v1.types import text_annotation +from google.cloud.vision_v1.types import web_detection as gcv_web_detection +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import latlng_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1', + manifest={ + 'Likelihood', + 'Feature', + 'ImageSource', + 'Image', + 'FaceAnnotation', + 'LocationInfo', + 'Property', + 'EntityAnnotation', + 'LocalizedObjectAnnotation', + 'SafeSearchAnnotation', + 'LatLongRect', + 'ColorInfo', + 'DominantColorsAnnotation', + 'ImageProperties', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'WebDetectionParams', + 'TextDetectionParams', + 'ImageContext', + 'AnnotateImageRequest', + 'ImageAnnotationContext', + 'AnnotateImageResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'AnnotateFileRequest', + 'AnnotateFileResponse', + 'BatchAnnotateFilesRequest', + 'BatchAnnotateFilesResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateImagesRequest', + 'AsyncBatchAnnotateImagesResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'InputConfig', + 'OutputConfig', + 'GcsSource', + 'GcsDestination', + 'OperationMetadata', + }, +) + + +class Likelihood(proto.Enum): + r"""A bucketized representation of likelihood, which is intended + to give clients highly stable results across model upgrades. + + Values: + UNKNOWN (0): + Unknown likelihood. + VERY_UNLIKELY (1): + It is very unlikely. + UNLIKELY (2): + It is unlikely. + POSSIBLE (3): + It is possible. + LIKELY (4): + It is likely. + VERY_LIKELY (5): + It is very likely. + """ + UNKNOWN = 0 + VERY_UNLIKELY = 1 + UNLIKELY = 2 + POSSIBLE = 3 + LIKELY = 4 + VERY_LIKELY = 5 + + +class Feature(proto.Message): + r"""The type of Google Cloud Vision API detection to perform, and the + maximum number of results to return for that type. Multiple + ``Feature`` objects can be specified in the ``features`` list. + + Attributes: + type_ (google.cloud.vision_v1.types.Feature.Type): + The feature type. + max_results (int): + Maximum number of results of this type. Does not apply to + ``TEXT_DETECTION``, ``DOCUMENT_TEXT_DETECTION``, or + ``CROP_HINTS``. + model (str): + Model to use for the feature. Supported values: + "builtin/stable" (the default if unset) and + "builtin/latest". ``DOCUMENT_TEXT_DETECTION`` and + ``TEXT_DETECTION`` also support "builtin/weekly" for the + bleeding edge release updated weekly. + """ + class Type(proto.Enum): + r"""Type of Google Cloud Vision API feature to be extracted. + + Values: + TYPE_UNSPECIFIED (0): + Unspecified feature type. + FACE_DETECTION (1): + Run face detection. + LANDMARK_DETECTION (2): + Run landmark detection. + LOGO_DETECTION (3): + Run logo detection. + LABEL_DETECTION (4): + Run label detection. + TEXT_DETECTION (5): + Run text detection / optical character recognition (OCR). + Text detection is optimized for areas of text within a + larger image; if the image is a document, use + ``DOCUMENT_TEXT_DETECTION`` instead. + DOCUMENT_TEXT_DETECTION (11): + Run dense text document OCR. Takes precedence when both + ``DOCUMENT_TEXT_DETECTION`` and ``TEXT_DETECTION`` are + present. + SAFE_SEARCH_DETECTION (6): + Run Safe Search to detect potentially unsafe + or undesirable content. + IMAGE_PROPERTIES (7): + Compute a set of image properties, such as + the image's dominant colors. + CROP_HINTS (9): + Run crop hints. + WEB_DETECTION (10): + Run web detection. + PRODUCT_SEARCH (12): + Run Product Search. + OBJECT_LOCALIZATION (19): + Run localizer for object detection. + """ + TYPE_UNSPECIFIED = 0 + FACE_DETECTION = 1 + LANDMARK_DETECTION = 2 + LOGO_DETECTION = 3 + LABEL_DETECTION = 4 + TEXT_DETECTION = 5 + DOCUMENT_TEXT_DETECTION = 11 + SAFE_SEARCH_DETECTION = 6 + IMAGE_PROPERTIES = 7 + CROP_HINTS = 9 + WEB_DETECTION = 10 + PRODUCT_SEARCH = 12 + OBJECT_LOCALIZATION = 19 + + type_: Type = proto.Field( + proto.ENUM, + number=1, + enum=Type, + ) + max_results: int = proto.Field( + proto.INT32, + number=2, + ) + model: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ImageSource(proto.Message): + r"""External image source (Google Cloud Storage or web URL image + location). + + Attributes: + gcs_image_uri (str): + **Use ``image_uri`` instead.** + + The Google Cloud Storage URI of the form + ``gs://bucket_name/object_name``. Object versioning is not + supported. See `Google Cloud Storage Request + URIs `__ + for more info. + image_uri (str): + The URI of the source image. Can be either: + + 1. A Google Cloud Storage URI of the form + ``gs://bucket_name/object_name``. Object versioning is + not supported. See `Google Cloud Storage Request + URIs `__ + for more info. + + 2. A publicly-accessible image HTTP/HTTPS URL. When fetching + images from HTTP/HTTPS URLs, Google cannot guarantee that + the request will be completed. Your request may fail if + the specified host denies the request (e.g. due to + request throttling or DOS prevention), or if Google + throttles requests to the site for abuse prevention. You + should not depend on externally-hosted images for + production applications. + + When both ``gcs_image_uri`` and ``image_uri`` are specified, + ``image_uri`` takes precedence. + """ + + gcs_image_uri: str = proto.Field( + proto.STRING, + number=1, + ) + image_uri: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Image(proto.Message): + r"""Client image to perform Google Cloud Vision API tasks over. + + Attributes: + content (bytes): + Image content, represented as a stream of bytes. Note: As + with all ``bytes`` fields, protobuffers use a pure binary + representation, whereas JSON representations use base64. + + Currently, this field only works for BatchAnnotateImages + requests. It does not work for AsyncBatchAnnotateImages + requests. + source (google.cloud.vision_v1.types.ImageSource): + Google Cloud Storage image location, or publicly-accessible + image URL. If both ``content`` and ``source`` are provided + for an image, ``content`` takes precedence and is used to + perform the image annotation request. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + source: 'ImageSource' = proto.Field( + proto.MESSAGE, + number=2, + message='ImageSource', + ) + + +class FaceAnnotation(proto.Message): + r"""A face annotation object contains the results of face + detection. + + Attributes: + bounding_poly (google.cloud.vision_v1.types.BoundingPoly): + The bounding polygon around the face. The coordinates of the + bounding box are in the original image's scale. The bounding + box is computed to "frame" the face in accordance with human + expectations. It is based on the landmarker results. Note + that one or more x and/or y coordinates may not be generated + in the ``BoundingPoly`` (the polygon will be unbounded) if + only a partial face appears in the image to be annotated. + fd_bounding_poly (google.cloud.vision_v1.types.BoundingPoly): + The ``fd_bounding_poly`` bounding polygon is tighter than + the ``boundingPoly``, and encloses only the skin part of the + face. Typically, it is used to eliminate the face from any + image analysis that detects the "amount of skin" visible in + an image. It is not based on the landmarker results, only on + the initial face detection, hence the fd (face detection) + prefix. + landmarks (MutableSequence[google.cloud.vision_v1.types.FaceAnnotation.Landmark]): + Detected face landmarks. + roll_angle (float): + Roll angle, which indicates the amount of + clockwise/anti-clockwise rotation of the face relative to + the image vertical about the axis perpendicular to the face. + Range [-180,180]. + pan_angle (float): + Yaw angle, which indicates the leftward/rightward angle that + the face is pointing relative to the vertical plane + perpendicular to the image. Range [-180,180]. + tilt_angle (float): + Pitch angle, which indicates the upwards/downwards angle + that the face is pointing relative to the image's horizontal + plane. Range [-180,180]. + detection_confidence (float): + Detection confidence. Range [0, 1]. + landmarking_confidence (float): + Face landmarking confidence. Range [0, 1]. + joy_likelihood (google.cloud.vision_v1.types.Likelihood): + Joy likelihood. + sorrow_likelihood (google.cloud.vision_v1.types.Likelihood): + Sorrow likelihood. + anger_likelihood (google.cloud.vision_v1.types.Likelihood): + Anger likelihood. + surprise_likelihood (google.cloud.vision_v1.types.Likelihood): + Surprise likelihood. + under_exposed_likelihood (google.cloud.vision_v1.types.Likelihood): + Under-exposed likelihood. + blurred_likelihood (google.cloud.vision_v1.types.Likelihood): + Blurred likelihood. + headwear_likelihood (google.cloud.vision_v1.types.Likelihood): + Headwear likelihood. + """ + + class Landmark(proto.Message): + r"""A face-specific landmark (for example, a face feature). + + Attributes: + type_ (google.cloud.vision_v1.types.FaceAnnotation.Landmark.Type): + Face landmark type. + position (google.cloud.vision_v1.types.Position): + Face landmark position. + """ + class Type(proto.Enum): + r"""Face landmark (feature) type. Left and right are defined from the + vantage of the viewer of the image without considering mirror + projections typical of photos. So, ``LEFT_EYE``, typically, is the + person's right eye. + + Values: + UNKNOWN_LANDMARK (0): + Unknown face landmark detected. Should not be + filled. + LEFT_EYE (1): + Left eye. + RIGHT_EYE (2): + Right eye. + LEFT_OF_LEFT_EYEBROW (3): + Left of left eyebrow. + RIGHT_OF_LEFT_EYEBROW (4): + Right of left eyebrow. + LEFT_OF_RIGHT_EYEBROW (5): + Left of right eyebrow. + RIGHT_OF_RIGHT_EYEBROW (6): + Right of right eyebrow. + MIDPOINT_BETWEEN_EYES (7): + Midpoint between eyes. + NOSE_TIP (8): + Nose tip. + UPPER_LIP (9): + Upper lip. + LOWER_LIP (10): + Lower lip. + MOUTH_LEFT (11): + Mouth left. + MOUTH_RIGHT (12): + Mouth right. + MOUTH_CENTER (13): + Mouth center. + NOSE_BOTTOM_RIGHT (14): + Nose, bottom right. + NOSE_BOTTOM_LEFT (15): + Nose, bottom left. + NOSE_BOTTOM_CENTER (16): + Nose, bottom center. + LEFT_EYE_TOP_BOUNDARY (17): + Left eye, top boundary. + LEFT_EYE_RIGHT_CORNER (18): + Left eye, right corner. + LEFT_EYE_BOTTOM_BOUNDARY (19): + Left eye, bottom boundary. + LEFT_EYE_LEFT_CORNER (20): + Left eye, left corner. + RIGHT_EYE_TOP_BOUNDARY (21): + Right eye, top boundary. + RIGHT_EYE_RIGHT_CORNER (22): + Right eye, right corner. + RIGHT_EYE_BOTTOM_BOUNDARY (23): + Right eye, bottom boundary. + RIGHT_EYE_LEFT_CORNER (24): + Right eye, left corner. + LEFT_EYEBROW_UPPER_MIDPOINT (25): + Left eyebrow, upper midpoint. + RIGHT_EYEBROW_UPPER_MIDPOINT (26): + Right eyebrow, upper midpoint. + LEFT_EAR_TRAGION (27): + Left ear tragion. + RIGHT_EAR_TRAGION (28): + Right ear tragion. + LEFT_EYE_PUPIL (29): + Left eye pupil. + RIGHT_EYE_PUPIL (30): + Right eye pupil. + FOREHEAD_GLABELLA (31): + Forehead glabella. + CHIN_GNATHION (32): + Chin gnathion. + CHIN_LEFT_GONION (33): + Chin left gonion. + CHIN_RIGHT_GONION (34): + Chin right gonion. + LEFT_CHEEK_CENTER (35): + Left cheek center. + RIGHT_CHEEK_CENTER (36): + Right cheek center. + """ + UNKNOWN_LANDMARK = 0 + LEFT_EYE = 1 + RIGHT_EYE = 2 + LEFT_OF_LEFT_EYEBROW = 3 + RIGHT_OF_LEFT_EYEBROW = 4 + LEFT_OF_RIGHT_EYEBROW = 5 + RIGHT_OF_RIGHT_EYEBROW = 6 + MIDPOINT_BETWEEN_EYES = 7 + NOSE_TIP = 8 + UPPER_LIP = 9 + LOWER_LIP = 10 + MOUTH_LEFT = 11 + MOUTH_RIGHT = 12 + MOUTH_CENTER = 13 + NOSE_BOTTOM_RIGHT = 14 + NOSE_BOTTOM_LEFT = 15 + NOSE_BOTTOM_CENTER = 16 + LEFT_EYE_TOP_BOUNDARY = 17 + LEFT_EYE_RIGHT_CORNER = 18 + LEFT_EYE_BOTTOM_BOUNDARY = 19 + LEFT_EYE_LEFT_CORNER = 20 + RIGHT_EYE_TOP_BOUNDARY = 21 + RIGHT_EYE_RIGHT_CORNER = 22 + RIGHT_EYE_BOTTOM_BOUNDARY = 23 + RIGHT_EYE_LEFT_CORNER = 24 + LEFT_EYEBROW_UPPER_MIDPOINT = 25 + RIGHT_EYEBROW_UPPER_MIDPOINT = 26 + LEFT_EAR_TRAGION = 27 + RIGHT_EAR_TRAGION = 28 + LEFT_EYE_PUPIL = 29 + RIGHT_EYE_PUPIL = 30 + FOREHEAD_GLABELLA = 31 + CHIN_GNATHION = 32 + CHIN_LEFT_GONION = 33 + CHIN_RIGHT_GONION = 34 + LEFT_CHEEK_CENTER = 35 + RIGHT_CHEEK_CENTER = 36 + + type_: 'FaceAnnotation.Landmark.Type' = proto.Field( + proto.ENUM, + number=3, + enum='FaceAnnotation.Landmark.Type', + ) + position: geometry.Position = proto.Field( + proto.MESSAGE, + number=4, + message=geometry.Position, + ) + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + fd_bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + landmarks: MutableSequence[Landmark] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=Landmark, + ) + roll_angle: float = proto.Field( + proto.FLOAT, + number=4, + ) + pan_angle: float = proto.Field( + proto.FLOAT, + number=5, + ) + tilt_angle: float = proto.Field( + proto.FLOAT, + number=6, + ) + detection_confidence: float = proto.Field( + proto.FLOAT, + number=7, + ) + landmarking_confidence: float = proto.Field( + proto.FLOAT, + number=8, + ) + joy_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + sorrow_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=10, + enum='Likelihood', + ) + anger_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=11, + enum='Likelihood', + ) + surprise_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=12, + enum='Likelihood', + ) + under_exposed_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=13, + enum='Likelihood', + ) + blurred_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=14, + enum='Likelihood', + ) + headwear_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=15, + enum='Likelihood', + ) + + +class LocationInfo(proto.Message): + r"""Detected entity location information. + + Attributes: + lat_lng (google.type.latlng_pb2.LatLng): + lat/long location coordinates. + """ + + lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + + +class Property(proto.Message): + r"""A ``Property`` consists of a user-supplied name/value pair. + + Attributes: + name (str): + Name of the property. + value (str): + Value of the property. + uint64_value (int): + Value of numeric properties. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + uint64_value: int = proto.Field( + proto.UINT64, + number=3, + ) + + +class EntityAnnotation(proto.Message): + r"""Set of detected entity features. + + Attributes: + mid (str): + Opaque entity ID. Some IDs may be available in `Google + Knowledge Graph Search + API `__. + locale (str): + The language code for the locale in which the entity textual + ``description`` is expressed. + description (str): + Entity textual description, expressed in its ``locale`` + language. + score (float): + Overall score of the result. Range [0, 1]. + confidence (float): + **Deprecated. Use ``score`` instead.** The accuracy of the + entity detection in an image. For example, for an image in + which the "Eiffel Tower" entity is detected, this field + represents the confidence that there is a tower in the query + image. Range [0, 1]. + topicality (float): + The relevancy of the ICA (Image Content Annotation) label to + the image. For example, the relevancy of "tower" is likely + higher to an image containing the detected "Eiffel Tower" + than to an image containing a detected distant towering + building, even though the confidence that there is a tower + in each image may be the same. Range [0, 1]. + bounding_poly (google.cloud.vision_v1.types.BoundingPoly): + Image region to which this entity belongs. Not produced for + ``LABEL_DETECTION`` features. + locations (MutableSequence[google.cloud.vision_v1.types.LocationInfo]): + The location information for the detected entity. Multiple + ``LocationInfo`` elements can be present because one + location may indicate the location of the scene in the + image, and another location may indicate the location of the + place where the image was taken. Location information is + usually present for landmarks. + properties (MutableSequence[google.cloud.vision_v1.types.Property]): + Some entities may have optional user-supplied ``Property`` + (name/value) fields, such a score or string that qualifies + the entity. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + locale: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + topicality: float = proto.Field( + proto.FLOAT, + number=6, + ) + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=7, + message=geometry.BoundingPoly, + ) + locations: MutableSequence['LocationInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message='LocationInfo', + ) + properties: MutableSequence['Property'] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message='Property', + ) + + +class LocalizedObjectAnnotation(proto.Message): + r"""Set of detected objects with bounding boxes. + + Attributes: + mid (str): + Object ID that should align with + EntityAnnotation mid. + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + name (str): + Object name, expressed in its ``language_code`` language. + score (float): + Score of the result. Range [0, 1]. + bounding_poly (google.cloud.vision_v1.types.BoundingPoly): + Image region to which this object belongs. + This must be populated. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=5, + message=geometry.BoundingPoly, + ) + + +class SafeSearchAnnotation(proto.Message): + r"""Set of features pertaining to the image, computed by computer + vision methods over safe-search verticals (for example, adult, + spoof, medical, violence). + + Attributes: + adult (google.cloud.vision_v1.types.Likelihood): + Represents the adult content likelihood for + the image. Adult content may contain elements + such as nudity, pornographic images or cartoons, + or sexual activities. + spoof (google.cloud.vision_v1.types.Likelihood): + Spoof likelihood. The likelihood that an + modification was made to the image's canonical + version to make it appear funny or offensive. + medical (google.cloud.vision_v1.types.Likelihood): + Likelihood that this is a medical image. + violence (google.cloud.vision_v1.types.Likelihood): + Likelihood that this image contains violent + content. + racy (google.cloud.vision_v1.types.Likelihood): + Likelihood that the request image contains + racy content. Racy content may include (but is + not limited to) skimpy or sheer clothing, + strategically covered nudity, lewd or + provocative poses, or close-ups of sensitive + body areas. + """ + + adult: 'Likelihood' = proto.Field( + proto.ENUM, + number=1, + enum='Likelihood', + ) + spoof: 'Likelihood' = proto.Field( + proto.ENUM, + number=2, + enum='Likelihood', + ) + medical: 'Likelihood' = proto.Field( + proto.ENUM, + number=3, + enum='Likelihood', + ) + violence: 'Likelihood' = proto.Field( + proto.ENUM, + number=4, + enum='Likelihood', + ) + racy: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + + +class LatLongRect(proto.Message): + r"""Rectangle determined by min and max ``LatLng`` pairs. + + Attributes: + min_lat_lng (google.type.latlng_pb2.LatLng): + Min lat/long pair. + max_lat_lng (google.type.latlng_pb2.LatLng): + Max lat/long pair. + """ + + min_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + max_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=2, + message=latlng_pb2.LatLng, + ) + + +class ColorInfo(proto.Message): + r"""Color information consists of RGB channels, score, and the + fraction of the image that the color occupies in the image. + + Attributes: + color (google.type.color_pb2.Color): + RGB components of the color. + score (float): + Image-specific score for this color. Value in range [0, 1]. + pixel_fraction (float): + The fraction of pixels the color occupies in the image. + Value in range [0, 1]. + """ + + color: color_pb2.Color = proto.Field( + proto.MESSAGE, + number=1, + message=color_pb2.Color, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + pixel_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class DominantColorsAnnotation(proto.Message): + r"""Set of dominant colors and their corresponding scores. + + Attributes: + colors (MutableSequence[google.cloud.vision_v1.types.ColorInfo]): + RGB color values with their score and pixel + fraction. + """ + + colors: MutableSequence['ColorInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ColorInfo', + ) + + +class ImageProperties(proto.Message): + r"""Stores image properties, such as dominant colors. + + Attributes: + dominant_colors (google.cloud.vision_v1.types.DominantColorsAnnotation): + If present, dominant colors completed + successfully. + """ + + dominant_colors: 'DominantColorsAnnotation' = proto.Field( + proto.MESSAGE, + number=1, + message='DominantColorsAnnotation', + ) + + +class CropHint(proto.Message): + r"""Single crop hint that is used to generate a new crop when + serving an image. + + Attributes: + bounding_poly (google.cloud.vision_v1.types.BoundingPoly): + The bounding polygon for the crop region. The + coordinates of the bounding box are in the + original image's scale. + confidence (float): + Confidence of this being a salient region. Range [0, 1]. + importance_fraction (float): + Fraction of importance of this salient region + with respect to the original image. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + importance_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class CropHintsAnnotation(proto.Message): + r"""Set of crop hints that are used to generate new crops when + serving images. + + Attributes: + crop_hints (MutableSequence[google.cloud.vision_v1.types.CropHint]): + Crop hint results. + """ + + crop_hints: MutableSequence['CropHint'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='CropHint', + ) + + +class CropHintsParams(proto.Message): + r"""Parameters for crop hints annotation request. + + Attributes: + aspect_ratios (MutableSequence[float]): + Aspect ratios in floats, representing the + ratio of the width to the height of the image. + For example, if the desired aspect ratio is 4/3, + the corresponding float value should be 1.33333. + If not specified, the best possible crop is + returned. The number of provided aspect ratios + is limited to a maximum of 16; any aspect ratios + provided after the 16th are ignored. + """ + + aspect_ratios: MutableSequence[float] = proto.RepeatedField( + proto.FLOAT, + number=1, + ) + + +class WebDetectionParams(proto.Message): + r"""Parameters for web detection request. + + Attributes: + include_geo_results (bool): + Whether to include results derived from the + geo information in the image. + """ + + include_geo_results: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class TextDetectionParams(proto.Message): + r"""Parameters for text detections. This is used to control + TEXT_DETECTION and DOCUMENT_TEXT_DETECTION features. + + Attributes: + enable_text_detection_confidence_score (bool): + By default, Cloud Vision API only includes confidence score + for DOCUMENT_TEXT_DETECTION result. Set the flag to true to + include confidence score for TEXT_DETECTION as well. + advanced_ocr_options (MutableSequence[str]): + A list of advanced OCR options to fine-tune + OCR behavior. + """ + + enable_text_detection_confidence_score: bool = proto.Field( + proto.BOOL, + number=9, + ) + advanced_ocr_options: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + + +class ImageContext(proto.Message): + r"""Image context and/or feature-specific parameters. + + Attributes: + lat_long_rect (google.cloud.vision_v1.types.LatLongRect): + Not used. + language_hints (MutableSequence[str]): + List of languages to use for TEXT_DETECTION. In most cases, + an empty value yields the best results since it enables + automatic language detection. For languages based on the + Latin alphabet, setting ``language_hints`` is not needed. In + rare cases, when the language of the text in the image is + known, setting a hint will help get better results (although + it will be a significant hindrance if the hint is wrong). + Text detection returns an error if one or more of the + specified languages is not one of the `supported + languages `__. + crop_hints_params (google.cloud.vision_v1.types.CropHintsParams): + Parameters for crop hints annotation request. + product_search_params (google.cloud.vision_v1.types.ProductSearchParams): + Parameters for product search. + web_detection_params (google.cloud.vision_v1.types.WebDetectionParams): + Parameters for web detection. + text_detection_params (google.cloud.vision_v1.types.TextDetectionParams): + Parameters for text detection and document + text detection. + """ + + lat_long_rect: 'LatLongRect' = proto.Field( + proto.MESSAGE, + number=1, + message='LatLongRect', + ) + language_hints: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + crop_hints_params: 'CropHintsParams' = proto.Field( + proto.MESSAGE, + number=4, + message='CropHintsParams', + ) + product_search_params: product_search.ProductSearchParams = proto.Field( + proto.MESSAGE, + number=5, + message=product_search.ProductSearchParams, + ) + web_detection_params: 'WebDetectionParams' = proto.Field( + proto.MESSAGE, + number=6, + message='WebDetectionParams', + ) + text_detection_params: 'TextDetectionParams' = proto.Field( + proto.MESSAGE, + number=12, + message='TextDetectionParams', + ) + + +class AnnotateImageRequest(proto.Message): + r"""Request for performing Google Cloud Vision API tasks over a + user-provided image, with user-requested features, and with + context information. + + Attributes: + image (google.cloud.vision_v1.types.Image): + The image to be processed. + features (MutableSequence[google.cloud.vision_v1.types.Feature]): + Requested features. + image_context (google.cloud.vision_v1.types.ImageContext): + Additional context that may accompany the + image. + """ + + image: 'Image' = proto.Field( + proto.MESSAGE, + number=1, + message='Image', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + + +class ImageAnnotationContext(proto.Message): + r"""If an image was produced from a file (e.g. a PDF), this + message gives information about the source of that image. + + Attributes: + uri (str): + The URI of the file used to produce the + image. + page_number (int): + If the file was a PDF or TIFF, this field + gives the page number within the file used to + produce the image. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + page_number: int = proto.Field( + proto.INT32, + number=2, + ) + + +class AnnotateImageResponse(proto.Message): + r"""Response to an image annotation request. + + Attributes: + face_annotations (MutableSequence[google.cloud.vision_v1.types.FaceAnnotation]): + If present, face detection has completed + successfully. + landmark_annotations (MutableSequence[google.cloud.vision_v1.types.EntityAnnotation]): + If present, landmark detection has completed + successfully. + logo_annotations (MutableSequence[google.cloud.vision_v1.types.EntityAnnotation]): + If present, logo detection has completed + successfully. + label_annotations (MutableSequence[google.cloud.vision_v1.types.EntityAnnotation]): + If present, label detection has completed + successfully. + localized_object_annotations (MutableSequence[google.cloud.vision_v1.types.LocalizedObjectAnnotation]): + If present, localized object detection has + completed successfully. This will be sorted + descending by confidence score. + text_annotations (MutableSequence[google.cloud.vision_v1.types.EntityAnnotation]): + If present, text (OCR) detection has + completed successfully. + full_text_annotation (google.cloud.vision_v1.types.TextAnnotation): + If present, text (OCR) detection or document + (OCR) text detection has completed successfully. + This annotation provides the structural + hierarchy for the OCR detected text. + safe_search_annotation (google.cloud.vision_v1.types.SafeSearchAnnotation): + If present, safe-search annotation has + completed successfully. + image_properties_annotation (google.cloud.vision_v1.types.ImageProperties): + If present, image properties were extracted + successfully. + crop_hints_annotation (google.cloud.vision_v1.types.CropHintsAnnotation): + If present, crop hints have completed + successfully. + web_detection (google.cloud.vision_v1.types.WebDetection): + If present, web detection has completed + successfully. + product_search_results (google.cloud.vision_v1.types.ProductSearchResults): + If present, product search has completed + successfully. + error (google.rpc.status_pb2.Status): + If set, represents the error message for the operation. Note + that filled-in image annotations are guaranteed to be + correct, even when ``error`` is set. + context (google.cloud.vision_v1.types.ImageAnnotationContext): + If present, contextual information is needed + to understand where this image comes from. + """ + + face_annotations: MutableSequence['FaceAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='FaceAnnotation', + ) + landmark_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='EntityAnnotation', + ) + logo_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='EntityAnnotation', + ) + label_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='EntityAnnotation', + ) + localized_object_annotations: MutableSequence['LocalizedObjectAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=22, + message='LocalizedObjectAnnotation', + ) + text_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='EntityAnnotation', + ) + full_text_annotation: text_annotation.TextAnnotation = proto.Field( + proto.MESSAGE, + number=12, + message=text_annotation.TextAnnotation, + ) + safe_search_annotation: 'SafeSearchAnnotation' = proto.Field( + proto.MESSAGE, + number=6, + message='SafeSearchAnnotation', + ) + image_properties_annotation: 'ImageProperties' = proto.Field( + proto.MESSAGE, + number=8, + message='ImageProperties', + ) + crop_hints_annotation: 'CropHintsAnnotation' = proto.Field( + proto.MESSAGE, + number=11, + message='CropHintsAnnotation', + ) + web_detection: gcv_web_detection.WebDetection = proto.Field( + proto.MESSAGE, + number=13, + message=gcv_web_detection.WebDetection, + ) + product_search_results: product_search.ProductSearchResults = proto.Field( + proto.MESSAGE, + number=14, + message=product_search.ProductSearchResults, + ) + error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=9, + message=status_pb2.Status, + ) + context: 'ImageAnnotationContext' = proto.Field( + proto.MESSAGE, + number=21, + message='ImageAnnotationContext', + ) + + +class BatchAnnotateImagesRequest(proto.Message): + r"""Multiple image annotation requests are batched into a single + service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + parent (str): + Optional. Target project and location to make a call. + + Format: ``projects/{project-id}/locations/{location-id}``. + + If no parent is specified, a region will be chosen + automatically. + + Supported location-ids: ``us``: USA country only, ``asia``: + East asia areas, like Japan, Taiwan, ``eu``: The European + Union. + + Example: ``projects/project-A/locations/eu``. + """ + + requests: MutableSequence['AnnotateImageRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageRequest', + ) + parent: str = proto.Field( + proto.STRING, + number=4, + ) + + +class BatchAnnotateImagesResponse(proto.Message): + r"""Response to a batch image annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1.types.AnnotateImageResponse]): + Individual responses to image annotation + requests within the batch. + """ + + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageResponse', + ) + + +class AnnotateFileRequest(proto.Message): + r"""A request to annotate one single file, e.g. a PDF, TIFF or + GIF file. + + Attributes: + input_config (google.cloud.vision_v1.types.InputConfig): + Required. Information about the input file. + features (MutableSequence[google.cloud.vision_v1.types.Feature]): + Required. Requested features. + image_context (google.cloud.vision_v1.types.ImageContext): + Additional context that may accompany the + image(s) in the file. + pages (MutableSequence[int]): + Pages of the file to perform image + annotation. + Pages starts from 1, we assume the first page of + the file is page 1. At most 5 pages are + supported per request. Pages can be negative. + + Page 1 means the first page. + Page 2 means the second page. + Page -1 means the last page. + Page -2 means the second to the last page. + + If the file is GIF instead of PDF or TIFF, page + refers to GIF frames. + + If this field is empty, by default the service + performs image annotation for the first 5 pages + of the file. + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + pages: MutableSequence[int] = proto.RepeatedField( + proto.INT32, + number=4, + ) + + +class AnnotateFileResponse(proto.Message): + r"""Response to a single file annotation request. A file may + contain one or more images, which individually have their own + responses. + + Attributes: + input_config (google.cloud.vision_v1.types.InputConfig): + Information about the file for which this + response is generated. + responses (MutableSequence[google.cloud.vision_v1.types.AnnotateImageResponse]): + Individual responses to images found within the file. This + field will be empty if the ``error`` field is set. + total_pages (int): + This field gives the total number of pages in + the file. + error (google.rpc.status_pb2.Status): + If set, represents the error message for the failed request. + The ``responses`` field will not be set in this case. + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='AnnotateImageResponse', + ) + total_pages: int = proto.Field( + proto.INT32, + number=3, + ) + error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=4, + message=status_pb2.Status, + ) + + +class BatchAnnotateFilesRequest(proto.Message): + r"""A list of requests to annotate files using the + BatchAnnotateFiles API. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1.types.AnnotateFileRequest]): + Required. The list of file annotation + requests. Right now we support only one + AnnotateFileRequest in + BatchAnnotateFilesRequest. + parent (str): + Optional. Target project and location to make a call. + + Format: ``projects/{project-id}/locations/{location-id}``. + + If no parent is specified, a region will be chosen + automatically. + + Supported location-ids: ``us``: USA country only, ``asia``: + East asia areas, like Japan, Taiwan, ``eu``: The European + Union. + + Example: ``projects/project-A/locations/eu``. + """ + + requests: MutableSequence['AnnotateFileRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateFileRequest', + ) + parent: str = proto.Field( + proto.STRING, + number=3, + ) + + +class BatchAnnotateFilesResponse(proto.Message): + r"""A list of file annotation responses. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1.types.AnnotateFileResponse]): + The list of file annotation responses, each + response corresponding to each + AnnotateFileRequest in + BatchAnnotateFilesRequest. + """ + + responses: MutableSequence['AnnotateFileResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateFileResponse', + ) + + +class AsyncAnnotateFileRequest(proto.Message): + r"""An offline file annotation request. + + Attributes: + input_config (google.cloud.vision_v1.types.InputConfig): + Required. Information about the input file. + features (MutableSequence[google.cloud.vision_v1.types.Feature]): + Required. Requested features. + image_context (google.cloud.vision_v1.types.ImageContext): + Additional context that may accompany the + image(s) in the file. + output_config (google.cloud.vision_v1.types.OutputConfig): + Required. The desired output location and + metadata (e.g. format). + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=4, + message='OutputConfig', + ) + + +class AsyncAnnotateFileResponse(proto.Message): + r"""The response for a single offline file annotation request. + + Attributes: + output_config (google.cloud.vision_v1.types.OutputConfig): + The output location and metadata from + AsyncAnnotateFileRequest. + """ + + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='OutputConfig', + ) + + +class AsyncBatchAnnotateImagesRequest(proto.Message): + r"""Request for async image annotation for a list of images. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + output_config (google.cloud.vision_v1.types.OutputConfig): + Required. The desired output location and + metadata (e.g. format). + parent (str): + Optional. Target project and location to make a call. + + Format: ``projects/{project-id}/locations/{location-id}``. + + If no parent is specified, a region will be chosen + automatically. + + Supported location-ids: ``us``: USA country only, ``asia``: + East asia areas, like Japan, Taiwan, ``eu``: The European + Union. + + Example: ``projects/project-A/locations/eu``. + """ + + requests: MutableSequence['AnnotateImageRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageRequest', + ) + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='OutputConfig', + ) + parent: str = proto.Field( + proto.STRING, + number=4, + ) + + +class AsyncBatchAnnotateImagesResponse(proto.Message): + r"""Response to an async batch image annotation request. + + Attributes: + output_config (google.cloud.vision_v1.types.OutputConfig): + The output location and metadata from + AsyncBatchAnnotateImagesRequest. + """ + + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='OutputConfig', + ) + + +class AsyncBatchAnnotateFilesRequest(proto.Message): + r"""Multiple async file annotation requests are batched into a + single service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1.types.AsyncAnnotateFileRequest]): + Required. Individual async file annotation + requests for this batch. + parent (str): + Optional. Target project and location to make a call. + + Format: ``projects/{project-id}/locations/{location-id}``. + + If no parent is specified, a region will be chosen + automatically. + + Supported location-ids: ``us``: USA country only, ``asia``: + East asia areas, like Japan, Taiwan, ``eu``: The European + Union. + + Example: ``projects/project-A/locations/eu``. + """ + + requests: MutableSequence['AsyncAnnotateFileRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AsyncAnnotateFileRequest', + ) + parent: str = proto.Field( + proto.STRING, + number=4, + ) + + +class AsyncBatchAnnotateFilesResponse(proto.Message): + r"""Response to an async batch file annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1.types.AsyncAnnotateFileResponse]): + The list of file annotation responses, one + for each request in + AsyncBatchAnnotateFilesRequest. + """ + + responses: MutableSequence['AsyncAnnotateFileResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AsyncAnnotateFileResponse', + ) + + +class InputConfig(proto.Message): + r"""The desired input location and metadata. + + Attributes: + gcs_source (google.cloud.vision_v1.types.GcsSource): + The Google Cloud Storage location to read the + input from. + content (bytes): + File content, represented as a stream of bytes. Note: As + with all ``bytes`` fields, protobuffers use a pure binary + representation, whereas JSON representations use base64. + + Currently, this field only works for BatchAnnotateFiles + requests. It does not work for AsyncBatchAnnotateFiles + requests. + mime_type (str): + The type of the file. Currently only + "application/pdf", "image/tiff" and "image/gif" + are supported. Wildcards are not supported. + """ + + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=1, + message='GcsSource', + ) + content: bytes = proto.Field( + proto.BYTES, + number=3, + ) + mime_type: str = proto.Field( + proto.STRING, + number=2, + ) + + +class OutputConfig(proto.Message): + r"""The desired output location and metadata. + + Attributes: + gcs_destination (google.cloud.vision_v1.types.GcsDestination): + The Google Cloud Storage location to write + the output(s) to. + batch_size (int): + The max number of response protos to put into each output + JSON file on Google Cloud Storage. The valid range is [1, + 100]. If not specified, the default value is 20. + + For example, for one pdf file with 100 pages, 100 response + protos will be generated. If ``batch_size`` = 20, then 5 + json files each containing 20 response protos will be + written under the prefix ``gcs_destination``.\ ``uri``. + + Currently, batch_size only applies to GcsDestination, with + potential future support for other output configurations. + """ + + gcs_destination: 'GcsDestination' = proto.Field( + proto.MESSAGE, + number=1, + message='GcsDestination', + ) + batch_size: int = proto.Field( + proto.INT32, + number=2, + ) + + +class GcsSource(proto.Message): + r"""The Google Cloud Storage location where the input will be + read from. + + Attributes: + uri (str): + Google Cloud Storage URI for the input file. + This must only be a Google Cloud Storage object. + Wildcards are not currently supported. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GcsDestination(proto.Message): + r"""The Google Cloud Storage location where the output will be + written to. + + Attributes: + uri (str): + Google Cloud Storage URI prefix where the results will be + stored. Results will be in JSON format and preceded by its + corresponding input URI prefix. This field can either + represent a gcs file prefix or gcs directory. In either + case, the uri should be unique because in order to get all + of the output files, you will need to do a wildcard gcs + search on the uri prefix you provide. + + Examples: + + - File Prefix: gs://bucket-name/here/filenameprefix The + output files will be created in gs://bucket-name/here/ + and the names of the output files will begin with + "filenameprefix". + + - Directory Prefix: gs://bucket-name/some/location/ The + output files will be created in + gs://bucket-name/some/location/ and the names of the + output files could be anything because there was no + filename prefix specified. + + If multiple outputs, each response is still + AnnotateFileResponse, each of which contains some subset of + the full list of AnnotateImageResponse. Multiple outputs can + happen if, for example, the output JSON is too large and + overflows into multiple sharded files. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class OperationMetadata(proto.Message): + r"""Contains metadata for the BatchAnnotateImages operation. + + Attributes: + state (google.cloud.vision_v1.types.OperationMetadata.State): + Current state of the batch operation. + create_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request was received. + update_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the operation result was last + updated. + """ + class State(proto.Enum): + r"""Batch operation states. + + Values: + STATE_UNSPECIFIED (0): + Invalid. + CREATED (1): + Request is received. + RUNNING (2): + Request is actively being processed. + DONE (3): + The batch processing is done. + CANCELLED (4): + The batch processing was cancelled. + """ + STATE_UNSPECIFIED = 0 + CREATED = 1 + RUNNING = 2 + DONE = 3 + CANCELLED = 4 + + state: State = proto.Field( + proto.ENUM, + number=1, + enum=State, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/types/product_search.py b/owl-bot-staging/v1/google/cloud/vision_v1/types/product_search.py new file mode 100644 index 00000000..be2b74e8 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/types/product_search.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1.types import geometry +from google.cloud.vision_v1.types import product_search_service +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1', + manifest={ + 'ProductSearchParams', + 'ProductSearchResults', + }, +) + + +class ProductSearchParams(proto.Message): + r"""Parameters for a product search request. + + Attributes: + bounding_poly (google.cloud.vision_v1.types.BoundingPoly): + The bounding polygon around the area of + interest in the image. If it is not specified, + system discretion will be applied. + product_set (str): + The resource name of a + [ProductSet][google.cloud.vision.v1.ProductSet] to be + searched for similar images. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID``. + product_categories (MutableSequence[str]): + The list of product categories to search in. + Currently, we only consider the first category, + and either "homegoods-v2", "apparel-v2", + "toys-v2", "packagedgoods-v1", or "general-v1" + should be specified. The legacy categories + "homegoods", "apparel", and "toys" are still + supported but will be deprecated. For new + products, please use "homegoods-v2", + "apparel-v2", or "toys-v2" for better product + search accuracy. It is recommended to migrate + existing products to these categories as well. + filter (str): + The filtering expression. This can be used to + restrict search results based on Product labels. + We currently support an AND of OR of key-value + expressions, where each expression within an OR + must have the same key. An '=' should be used to + connect the key and value. + + For example, "(color = red OR color = blue) AND + brand = Google" is acceptable, but "(color = red + OR brand = Google)" is not acceptable. "color: + red" is not acceptable because it uses a ':' + instead of an '='. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=9, + message=geometry.BoundingPoly, + ) + product_set: str = proto.Field( + proto.STRING, + number=6, + ) + product_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + filter: str = proto.Field( + proto.STRING, + number=8, + ) + + +class ProductSearchResults(proto.Message): + r"""Results for a product search request. + + Attributes: + index_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp of the index which provided these + results. Products added to the product set and + products removed from the product set after this + time are not reflected in the current results. + results (MutableSequence[google.cloud.vision_v1.types.ProductSearchResults.Result]): + List of results, one for each product match. + product_grouped_results (MutableSequence[google.cloud.vision_v1.types.ProductSearchResults.GroupedResult]): + List of results grouped by products detected + in the query image. Each entry corresponds to + one bounding polygon in the query image, and + contains the matching products specific to that + region. There may be duplicate product matches + in the union of all the per-product results. + """ + + class Result(proto.Message): + r"""Information about a product. + + Attributes: + product (google.cloud.vision_v1.types.Product): + The Product. + score (float): + A confidence level on the match, ranging from + 0 (no confidence) to 1 (full confidence). + image (str): + The resource name of the image from the + product that is the closest match to the query. + """ + + product: product_search_service.Product = proto.Field( + proto.MESSAGE, + number=1, + message=product_search_service.Product, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + image: str = proto.Field( + proto.STRING, + number=3, + ) + + class ObjectAnnotation(proto.Message): + r"""Prediction for what the object in the bounding box is. + + Attributes: + mid (str): + Object ID that should align with + EntityAnnotation mid. + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + name (str): + Object name, expressed in its ``language_code`` language. + score (float): + Score of the result. Range [0, 1]. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + + class GroupedResult(proto.Message): + r"""Information about the products similar to a single product in + a query image. + + Attributes: + bounding_poly (google.cloud.vision_v1.types.BoundingPoly): + The bounding polygon around the product + detected in the query image. + results (MutableSequence[google.cloud.vision_v1.types.ProductSearchResults.Result]): + List of results, one for each product match. + object_annotations (MutableSequence[google.cloud.vision_v1.types.ProductSearchResults.ObjectAnnotation]): + List of generic predictions for the object in + the bounding box. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + results: MutableSequence['ProductSearchResults.Result'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='ProductSearchResults.Result', + ) + object_annotations: MutableSequence['ProductSearchResults.ObjectAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='ProductSearchResults.ObjectAnnotation', + ) + + index_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + results: MutableSequence[Result] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=Result, + ) + product_grouped_results: MutableSequence[GroupedResult] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=GroupedResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/types/product_search_service.py b/owl-bot-staging/v1/google/cloud/vision_v1/types/product_search_service.py new file mode 100644 index 00000000..19c8b789 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/types/product_search_service.py @@ -0,0 +1,1114 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1.types import geometry +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1', + manifest={ + 'Product', + 'ProductSet', + 'ReferenceImage', + 'CreateProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'GetProductRequest', + 'UpdateProductRequest', + 'DeleteProductRequest', + 'CreateProductSetRequest', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'GetProductSetRequest', + 'UpdateProductSetRequest', + 'DeleteProductSetRequest', + 'CreateReferenceImageRequest', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'GetReferenceImageRequest', + 'DeleteReferenceImageRequest', + 'AddProductToProductSetRequest', + 'RemoveProductFromProductSetRequest', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'BatchOperationMetadata', + 'ProductSetPurgeConfig', + 'PurgeProductsRequest', + }, +) + + +class Product(proto.Message): + r"""A Product contains ReferenceImages. + + Attributes: + name (str): + The resource name of the product. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This field is ignored when creating a product. + display_name (str): + The user-provided name for this Product. Must + not be empty. Must be at most 4096 characters + long. + description (str): + User-provided metadata to be stored with this + product. Must be at most 4096 characters long. + product_category (str): + Immutable. The category for the product + identified by the reference image. This should + be one of "homegoods-v2", "apparel-v2", + "toys-v2", "packagedgoods-v1" or "general-v1". + The legacy categories "homegoods", "apparel", + and "toys" are still supported, but these should + not be used for new products. + product_labels (MutableSequence[google.cloud.vision_v1.types.Product.KeyValue]): + Key-value pairs that can be attached to a product. At query + time, constraints can be specified based on the + product_labels. + + Note that integer values can be provided as strings, e.g. + "1199". Only strings with integer values can match a + range-based restriction which is to be supported soon. + + Multiple values can be assigned to the same key. One product + may have up to 500 product_labels. + + Notice that the total number of distinct product_labels over + all products in one ProductSet cannot exceed 1M, otherwise + the product search pipeline will refuse to work for that + ProductSet. + """ + + class KeyValue(proto.Message): + r"""A product label represented as a key-value pair. + + Attributes: + key (str): + The key of the label attached to the product. + Cannot be empty and cannot exceed 128 bytes. + value (str): + The value of the label attached to the + product. Cannot be empty and cannot exceed 128 + bytes. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + product_category: str = proto.Field( + proto.STRING, + number=4, + ) + product_labels: MutableSequence[KeyValue] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=KeyValue, + ) + + +class ProductSet(proto.Message): + r"""A ProductSet contains Products. A ProductSet can contain a + maximum of 1 million reference images. If the limit is exceeded, + periodic indexing will fail. + + Attributes: + name (str): + The resource name of the ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID``. + + This field is ignored when creating a ProductSet. + display_name (str): + The user-provided name for this ProductSet. + Must not be empty. Must be at most 4096 + characters long. + index_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time at which this + ProductSet was last indexed. Query results will + reflect all updates before this time. If this + ProductSet has never been indexed, this + timestamp is the default value + "1970-01-01T00:00:00Z". + + This field is ignored when creating a + ProductSet. + index_error (google.rpc.status_pb2.Status): + Output only. If there was an error with + indexing the product set, the field is + populated. + + This field is ignored when creating a + ProductSet. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + index_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + index_error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=4, + message=status_pb2.Status, + ) + + +class ReferenceImage(proto.Message): + r"""A ``ReferenceImage`` represents a product image and its associated + metadata, such as bounding boxes. + + Attributes: + name (str): + The resource name of the reference image. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This field is ignored when creating a reference image. + uri (str): + Required. The Google Cloud Storage URI of the reference + image. + + The URI must start with ``gs://``. + bounding_polys (MutableSequence[google.cloud.vision_v1.types.BoundingPoly]): + Optional. Bounding polygons around the areas + of interest in the reference image. If this + field is empty, the system will try to detect + regions of interest. At most 10 bounding + polygons will be used. + + The provided shape is converted into a + non-rotated rectangle. Once converted, the small + edge of the rectangle must be greater than or + equal to 300 pixels. The aspect ratio must be + 1:4 or less (i.e. 1:3 is ok; 1:5 is not). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + uri: str = proto.Field( + proto.STRING, + number=2, + ) + bounding_polys: MutableSequence[geometry.BoundingPoly] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=geometry.BoundingPoly, + ) + + +class CreateProductRequest(proto.Message): + r"""Request message for the ``CreateProduct`` method. + + Attributes: + parent (str): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + product (google.cloud.vision_v1.types.Product): + Required. The product to create. + product_id (str): + A user-supplied resource id for this Product. If set, the + server will attempt to use this value as the resource id. If + it is already in use, an error is returned with code + ALREADY_EXISTS. Must be at most 128 characters long. It + cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product: 'Product' = proto.Field( + proto.MESSAGE, + number=2, + message='Product', + ) + product_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsRequest(proto.Message): + r"""Request message for the ``ListProducts`` method. + + Attributes: + parent (str): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsResponse(proto.Message): + r"""Response message for the ``ListProducts`` method. + + Attributes: + products (MutableSequence[google.cloud.vision_v1.types.Product]): + List of products. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Product', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetProductRequest(proto.Message): + r"""Request message for the ``GetProduct`` method. + + Attributes: + name (str): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductRequest(proto.Message): + r"""Request message for the ``UpdateProduct`` method. + + Attributes: + product (google.cloud.vision_v1.types.Product): + Required. The Product resource which replaces + the one on the server. product.name is + immutable. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that specifies + which fields to update. If update_mask isn't specified, all + mutable fields are to be updated. Valid mask paths include + ``product_labels``, ``display_name``, and ``description``. + """ + + product: 'Product' = proto.Field( + proto.MESSAGE, + number=1, + message='Product', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteProductRequest(proto.Message): + r"""Request message for the ``DeleteProduct`` method. + + Attributes: + name (str): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateProductSetRequest(proto.Message): + r"""Request message for the ``CreateProductSet`` method. + + Attributes: + parent (str): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + product_set (google.cloud.vision_v1.types.ProductSet): + Required. The ProductSet to create. + product_set_id (str): + A user-supplied resource id for this ProductSet. If set, the + server will attempt to use this value as the resource id. If + it is already in use, an error is returned with code + ALREADY_EXISTS. Must be at most 128 characters long. It + cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product_set: 'ProductSet' = proto.Field( + proto.MESSAGE, + number=2, + message='ProductSet', + ) + product_set_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductSetsRequest(proto.Message): + r"""Request message for the ``ListProductSets`` method. + + Attributes: + parent (str): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductSetsResponse(proto.Message): + r"""Response message for the ``ListProductSets`` method. + + Attributes: + product_sets (MutableSequence[google.cloud.vision_v1.types.ProductSet]): + List of ProductSets. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + product_sets: MutableSequence['ProductSet'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ProductSet', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetProductSetRequest(proto.Message): + r"""Request message for the ``GetProductSet`` method. + + Attributes: + name (str): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductSetRequest(proto.Message): + r"""Request message for the ``UpdateProductSet`` method. + + Attributes: + product_set (google.cloud.vision_v1.types.ProductSet): + Required. The ProductSet resource which + replaces the one on the server. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that specifies + which fields to update. If update_mask isn't specified, all + mutable fields are to be updated. Valid mask path is + ``display_name``. + """ + + product_set: 'ProductSet' = proto.Field( + proto.MESSAGE, + number=1, + message='ProductSet', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteProductSetRequest(proto.Message): + r"""Request message for the ``DeleteProductSet`` method. + + Attributes: + name (str): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateReferenceImageRequest(proto.Message): + r"""Request message for the ``CreateReferenceImage`` method. + + Attributes: + parent (str): + Required. Resource name of the product in which to create + the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + reference_image (google.cloud.vision_v1.types.ReferenceImage): + Required. The reference image to create. + If an image ID is specified, it is ignored. + reference_image_id (str): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value as + the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + reference_image: 'ReferenceImage' = proto.Field( + proto.MESSAGE, + number=2, + message='ReferenceImage', + ) + reference_image_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListReferenceImagesRequest(proto.Message): + r"""Request message for the ``ListReferenceImages`` method. + + Attributes: + parent (str): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + A token identifying a page of results to be returned. This + is the value of ``nextPageToken`` returned in a previous + reference image list request. + + Defaults to the first page if not specified. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListReferenceImagesResponse(proto.Message): + r"""Response message for the ``ListReferenceImages`` method. + + Attributes: + reference_images (MutableSequence[google.cloud.vision_v1.types.ReferenceImage]): + The list of reference images. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + next_page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + @property + def raw_page(self): + return self + + reference_images: MutableSequence['ReferenceImage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ReferenceImage', + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetReferenceImageRequest(proto.Message): + r"""Request message for the ``GetReferenceImage`` method. + + Attributes: + name (str): + Required. The resource name of the ReferenceImage to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class DeleteReferenceImageRequest(proto.Message): + r"""Request message for the ``DeleteReferenceImage`` method. + + Attributes: + name (str): + Required. The resource name of the reference image to + delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AddProductToProductSetRequest(proto.Message): + r"""Request message for the ``AddProductToProductSet`` method. + + Attributes: + name (str): + Required. The resource name for the ProductSet to modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + product (str): + Required. The resource name for the Product to be added to + this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + product: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RemoveProductFromProductSetRequest(proto.Message): + r"""Request message for the ``RemoveProductFromProductSet`` method. + + Attributes: + name (str): + Required. The resource name for the ProductSet to modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + product (str): + Required. The resource name for the Product to be removed + from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + product: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ListProductsInProductSetRequest(proto.Message): + r"""Request message for the ``ListProductsInProductSet`` method. + + Attributes: + name (str): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsInProductSetResponse(proto.Message): + r"""Response message for the ``ListProductsInProductSet`` method. + + Attributes: + products (MutableSequence[google.cloud.vision_v1.types.Product]): + The list of Products. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Product', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ImportProductSetsGcsSource(proto.Message): + r"""The Google Cloud Storage location for a csv file which + preserves a list of ImportProductSetRequests in each line. + + Attributes: + csv_file_uri (str): + The Google Cloud Storage URI of the input csv file. + + The URI must start with ``gs://``. + + The format of the input csv file should be one image per + line. In each line, there are 8 columns. + + 1. image-uri + 2. image-id + 3. product-set-id + 4. product-id + 5. product-category + 6. product-display-name + 7. labels + 8. bounding-poly + + The ``image-uri``, ``product-set-id``, ``product-id``, and + ``product-category`` columns are required. All other columns + are optional. + + If the ``ProductSet`` or ``Product`` specified by the + ``product-set-id`` and ``product-id`` values does not exist, + then the system will create a new ``ProductSet`` or + ``Product`` for the image. In this case, the + ``product-display-name`` column refers to + [display_name][google.cloud.vision.v1.Product.display_name], + the ``product-category`` column refers to + [product_category][google.cloud.vision.v1.Product.product_category], + and the ``labels`` column refers to + [product_labels][google.cloud.vision.v1.Product.product_labels]. + + The ``image-id`` column is optional but must be unique if + provided. If it is empty, the system will automatically + assign a unique id to the image. + + The ``product-display-name`` column is optional. If it is + empty, the system sets the + [display_name][google.cloud.vision.v1.Product.display_name] + field for the product to a space (" "). You can update the + ``display_name`` later by using the API. + + If a ``Product`` with the specified ``product-id`` already + exists, then the system ignores the + ``product-display-name``, ``product-category``, and + ``labels`` columns. + + The ``labels`` column (optional) is a line containing a list + of comma-separated key-value pairs, in the following format: + + :: + + "key_1=value_1,key_2=value_2,...,key_n=value_n" + + The ``bounding-poly`` column (optional) identifies one + region of interest from the image in the same manner as + ``CreateReferenceImage``. If you do not specify the + ``bounding-poly`` column, then the system will try to detect + regions of interest automatically. + + At most one ``bounding-poly`` column is allowed per line. If + the image contains multiple regions of interest, add a line + to the CSV file that includes the same product information, + and the ``bounding-poly`` values for each region of + interest. + + The ``bounding-poly`` column must contain an even number of + comma-separated numbers, in the format + "p1_x,p1_y,p2_x,p2_y,...,pn_x,pn_y". Use non-negative + integers for absolute bounding polygons, and float values in + [0, 1] for normalized bounding polygons. + + The system will resize the image if the image resolution is + too large to process (larger than 20MP). + """ + + csv_file_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ImportProductSetsInputConfig(proto.Message): + r"""The input content for the ``ImportProductSets`` method. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_source (google.cloud.vision_v1.types.ImportProductSetsGcsSource): + The Google Cloud Storage location for a csv + file which preserves a list of + ImportProductSetRequests in each line. + + This field is a member of `oneof`_ ``source``. + """ + + gcs_source: 'ImportProductSetsGcsSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='ImportProductSetsGcsSource', + ) + + +class ImportProductSetsRequest(proto.Message): + r"""Request message for the ``ImportProductSets`` method. + + Attributes: + parent (str): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + input_config (google.cloud.vision_v1.types.ImportProductSetsInputConfig): + Required. The input content for the list of + requests. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'ImportProductSetsInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportProductSetsInputConfig', + ) + + +class ImportProductSetsResponse(proto.Message): + r"""Response message for the ``ImportProductSets`` method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + Attributes: + reference_images (MutableSequence[google.cloud.vision_v1.types.ReferenceImage]): + The list of reference_images that are imported successfully. + statuses (MutableSequence[google.rpc.status_pb2.Status]): + The rpc status for each ImportProductSet request, including + both successes and errors. + + The number of statuses here matches the number of lines in + the csv file, and statuses[i] stores the success or failure + status of processing the i-th line of the csv, starting from + line 0. + """ + + reference_images: MutableSequence['ReferenceImage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ReferenceImage', + ) + statuses: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=status_pb2.Status, + ) + + +class BatchOperationMetadata(proto.Message): + r"""Metadata for the batch operations such as the current state. + + This is included in the ``metadata`` field of the ``Operation`` + returned by the ``GetOperation`` call of the + ``google::longrunning::Operations`` service. + + Attributes: + state (google.cloud.vision_v1.types.BatchOperationMetadata.State): + The current state of the batch operation. + submit_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request was submitted + to the server. + end_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request is finished and + [google.longrunning.Operation.done][google.longrunning.Operation.done] + is set to true. + """ + class State(proto.Enum): + r"""Enumerates the possible states that the batch request can be + in. + + Values: + STATE_UNSPECIFIED (0): + Invalid. + PROCESSING (1): + Request is actively being processed. + SUCCESSFUL (2): + The request is done and at least one item has + been successfully processed. + FAILED (3): + The request is done and no item has been + successfully processed. + CANCELLED (4): + The request is done after the + longrunning.Operations.CancelOperation has been + called by the user. Any records that were + processed before the cancel command are output + as specified in the request. + """ + STATE_UNSPECIFIED = 0 + PROCESSING = 1 + SUCCESSFUL = 2 + FAILED = 3 + CANCELLED = 4 + + state: State = proto.Field( + proto.ENUM, + number=1, + enum=State, + ) + submit_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + + +class ProductSetPurgeConfig(proto.Message): + r"""Config to control which ProductSet contains the Products to + be deleted. + + Attributes: + product_set_id (str): + The ProductSet that contains the Products to delete. If a + Product is a member of product_set_id in addition to other + ProductSets, the Product will still be deleted. + """ + + product_set_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +class PurgeProductsRequest(proto.Message): + r"""Request message for the ``PurgeProducts`` method. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + product_set_purge_config (google.cloud.vision_v1.types.ProductSetPurgeConfig): + Specify which ProductSet contains the + Products to be deleted. + + This field is a member of `oneof`_ ``target``. + delete_orphan_products (bool): + If delete_orphan_products is true, all Products that are not + in any ProductSet will be deleted. + + This field is a member of `oneof`_ ``target``. + parent (str): + Required. The project and location in which the Products + should be deleted. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + force (bool): + The default value is false. Override this + value to true to actually perform the purge. + """ + + product_set_purge_config: 'ProductSetPurgeConfig' = proto.Field( + proto.MESSAGE, + number=2, + oneof='target', + message='ProductSetPurgeConfig', + ) + delete_orphan_products: bool = proto.Field( + proto.BOOL, + number=3, + oneof='target', + ) + parent: str = proto.Field( + proto.STRING, + number=1, + ) + force: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/types/text_annotation.py b/owl-bot-staging/v1/google/cloud/vision_v1/types/text_annotation.py new file mode 100644 index 00000000..c98ec068 --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/types/text_annotation.py @@ -0,0 +1,429 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1.types import geometry + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1', + manifest={ + 'TextAnnotation', + 'Page', + 'Block', + 'Paragraph', + 'Word', + 'Symbol', + }, +) + + +class TextAnnotation(proto.Message): + r"""TextAnnotation contains a structured representation of OCR extracted + text. The hierarchy of an OCR extracted text structure is like this: + TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol Each + structural component, starting from Page, may further have their own + properties. Properties describe detected languages, breaks etc.. + Please refer to the + [TextAnnotation.TextProperty][google.cloud.vision.v1.TextAnnotation.TextProperty] + message definition below for more detail. + + Attributes: + pages (MutableSequence[google.cloud.vision_v1.types.Page]): + List of pages detected by OCR. + text (str): + UTF-8 text detected on the pages. + """ + + class DetectedLanguage(proto.Message): + r"""Detected language for a structural component. + + Attributes: + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + confidence (float): + Confidence of detected language. Range [0, 1]. + """ + + language_code: str = proto.Field( + proto.STRING, + number=1, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class DetectedBreak(proto.Message): + r"""Detected start or end of a structural component. + + Attributes: + type_ (google.cloud.vision_v1.types.TextAnnotation.DetectedBreak.BreakType): + Detected break type. + is_prefix (bool): + True if break prepends the element. + """ + class BreakType(proto.Enum): + r"""Enum to denote the type of break found. New line, space etc. + + Values: + UNKNOWN (0): + Unknown break label type. + SPACE (1): + Regular space. + SURE_SPACE (2): + Sure space (very wide). + EOL_SURE_SPACE (3): + Line-wrapping break. + HYPHEN (4): + End-line hyphen that is not present in text; does not + co-occur with ``SPACE``, ``LEADER_SPACE``, or + ``LINE_BREAK``. + LINE_BREAK (5): + Line break that ends a paragraph. + """ + UNKNOWN = 0 + SPACE = 1 + SURE_SPACE = 2 + EOL_SURE_SPACE = 3 + HYPHEN = 4 + LINE_BREAK = 5 + + type_: 'TextAnnotation.DetectedBreak.BreakType' = proto.Field( + proto.ENUM, + number=1, + enum='TextAnnotation.DetectedBreak.BreakType', + ) + is_prefix: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class TextProperty(proto.Message): + r"""Additional information detected on the structural component. + + Attributes: + detected_languages (MutableSequence[google.cloud.vision_v1.types.TextAnnotation.DetectedLanguage]): + A list of detected languages together with + confidence. + detected_break (google.cloud.vision_v1.types.TextAnnotation.DetectedBreak): + Detected start or end of a text segment. + """ + + detected_languages: MutableSequence['TextAnnotation.DetectedLanguage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='TextAnnotation.DetectedLanguage', + ) + detected_break: 'TextAnnotation.DetectedBreak' = proto.Field( + proto.MESSAGE, + number=2, + message='TextAnnotation.DetectedBreak', + ) + + pages: MutableSequence['Page'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Page', + ) + text: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Page(proto.Message): + r"""Detected page from OCR. + + Attributes: + property (google.cloud.vision_v1.types.TextAnnotation.TextProperty): + Additional information detected on the page. + width (int): + Page width. For PDFs the unit is points. For + images (including TIFFs) the unit is pixels. + height (int): + Page height. For PDFs the unit is points. For + images (including TIFFs) the unit is pixels. + blocks (MutableSequence[google.cloud.vision_v1.types.Block]): + List of blocks of text, images etc on this + page. + confidence (float): + Confidence of the OCR results on the page. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + width: int = proto.Field( + proto.INT32, + number=2, + ) + height: int = proto.Field( + proto.INT32, + number=3, + ) + blocks: MutableSequence['Block'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='Block', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Block(proto.Message): + r"""Logical element on the page. + + Attributes: + property (google.cloud.vision_v1.types.TextAnnotation.TextProperty): + Additional information detected for the + block. + bounding_box (google.cloud.vision_v1.types.BoundingPoly): + The bounding box for the block. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: + + :: + + 0----1 + | | + 3----2 + + - when it's rotated 180 degrees around the top-left corner + it becomes: + + :: + + 2----3 + | | + 1----0 + + and the vertex order will still be (0, 1, 2, 3). + paragraphs (MutableSequence[google.cloud.vision_v1.types.Paragraph]): + List of paragraphs in this block (if this + blocks is of type text). + block_type (google.cloud.vision_v1.types.Block.BlockType): + Detected block type (text, image etc) for + this block. + confidence (float): + Confidence of the OCR results on the block. Range [0, 1]. + """ + class BlockType(proto.Enum): + r"""Type of a block (text, image etc) as identified by OCR. + + Values: + UNKNOWN (0): + Unknown block type. + TEXT (1): + Regular text block. + TABLE (2): + Table block. + PICTURE (3): + Image block. + RULER (4): + Horizontal/vertical line box. + BARCODE (5): + Barcode block. + """ + UNKNOWN = 0 + TEXT = 1 + TABLE = 2 + PICTURE = 3 + RULER = 4 + BARCODE = 5 + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + paragraphs: MutableSequence['Paragraph'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Paragraph', + ) + block_type: BlockType = proto.Field( + proto.ENUM, + number=4, + enum=BlockType, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Paragraph(proto.Message): + r"""Structural unit of text representing a number of words in + certain order. + + Attributes: + property (google.cloud.vision_v1.types.TextAnnotation.TextProperty): + Additional information detected for the + paragraph. + bounding_box (google.cloud.vision_v1.types.BoundingPoly): + The bounding box for the paragraph. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertex order will + still be (0, 1, 2, 3). + words (MutableSequence[google.cloud.vision_v1.types.Word]): + List of all words in this paragraph. + confidence (float): + Confidence of the OCR results for the paragraph. Range [0, + 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + words: MutableSequence['Word'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Word', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Word(proto.Message): + r"""A word representation. + + Attributes: + property (google.cloud.vision_v1.types.TextAnnotation.TextProperty): + Additional information detected for the word. + bounding_box (google.cloud.vision_v1.types.BoundingPoly): + The bounding box for the word. The vertices are in the order + of top-left, top-right, bottom-right, bottom-left. When a + rotation of the bounding box is detected the rotation is + represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertex order will + still be (0, 1, 2, 3). + symbols (MutableSequence[google.cloud.vision_v1.types.Symbol]): + List of symbols in the word. + The order of the symbols follows the natural + reading order. + confidence (float): + Confidence of the OCR results for the word. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + symbols: MutableSequence['Symbol'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Symbol', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Symbol(proto.Message): + r"""A single symbol representation. + + Attributes: + property (google.cloud.vision_v1.types.TextAnnotation.TextProperty): + Additional information detected for the + symbol. + bounding_box (google.cloud.vision_v1.types.BoundingPoly): + The bounding box for the symbol. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertex order will + still be (0, 1, 2, 3). + text (str): + The actual UTF-8 representation of the + symbol. + confidence (float): + Confidence of the OCR results for the symbol. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + text: str = proto.Field( + proto.STRING, + number=3, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1/google/cloud/vision_v1/types/web_detection.py b/owl-bot-staging/v1/google/cloud/vision_v1/types/web_detection.py new file mode 100644 index 00000000..9beef77a --- /dev/null +++ b/owl-bot-staging/v1/google/cloud/vision_v1/types/web_detection.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1', + manifest={ + 'WebDetection', + }, +) + + +class WebDetection(proto.Message): + r"""Relevant information for the image from the Internet. + + Attributes: + web_entities (MutableSequence[google.cloud.vision_v1.types.WebDetection.WebEntity]): + Deduced entities from similar images on the + Internet. + full_matching_images (MutableSequence[google.cloud.vision_v1.types.WebDetection.WebImage]): + Fully matching images from the Internet. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1.types.WebDetection.WebImage]): + Partial matching images from the Internet. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + pages_with_matching_images (MutableSequence[google.cloud.vision_v1.types.WebDetection.WebPage]): + Web pages containing the matching images from + the Internet. + visually_similar_images (MutableSequence[google.cloud.vision_v1.types.WebDetection.WebImage]): + The visually similar image results. + best_guess_labels (MutableSequence[google.cloud.vision_v1.types.WebDetection.WebLabel]): + The service's best guess as to the topic of + the request image. Inferred from similar images + on the open web. + """ + + class WebEntity(proto.Message): + r"""Entity deduced from similar images on the Internet. + + Attributes: + entity_id (str): + Opaque entity ID. + score (float): + Overall relevancy score for the entity. + Not normalized and not comparable across + different image queries. + description (str): + Canonical description of the entity, in + English. + """ + + entity_id: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + + class WebImage(proto.Message): + r"""Metadata for online images. + + Attributes: + url (str): + The result image URL. + score (float): + (Deprecated) Overall relevancy score for the + image. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class WebPage(proto.Message): + r"""Metadata for web pages. + + Attributes: + url (str): + The result web page URL. + score (float): + (Deprecated) Overall relevancy score for the + web page. + page_title (str): + Title for the web page, may contain HTML + markups. + full_matching_images (MutableSequence[google.cloud.vision_v1.types.WebDetection.WebImage]): + Fully matching images on the page. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1.types.WebDetection.WebImage]): + Partial matching images on the page. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + page_title: str = proto.Field( + proto.STRING, + number=3, + ) + full_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='WebDetection.WebImage', + ) + partial_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='WebDetection.WebImage', + ) + + class WebLabel(proto.Message): + r"""Label to provide extra metadata for the web detection. + + Attributes: + label (str): + Label for extra metadata. + language_code (str): + The BCP-47 language code for ``label``, such as "en-US" or + "sr-Latn". For more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + """ + + label: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + + web_entities: MutableSequence[WebEntity] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=WebEntity, + ) + full_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=WebImage, + ) + partial_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=WebImage, + ) + pages_with_matching_images: MutableSequence[WebPage] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=WebPage, + ) + visually_similar_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=WebImage, + ) + best_guess_labels: MutableSequence[WebLabel] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=WebLabel, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1/mypy.ini b/owl-bot-staging/v1/mypy.ini new file mode 100644 index 00000000..574c5aed --- /dev/null +++ b/owl-bot-staging/v1/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/v1/noxfile.py b/owl-bot-staging/v1/noxfile.py new file mode 100644 index 00000000..48ba72e9 --- /dev/null +++ b/owl-bot-staging/v1/noxfile.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +import pathlib +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = subprocess.check_output([sys.executable, "setup.py", "--name"], encoding="utf-8") + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.11" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "lint_setup_py", +] + +@nox.session(python=ALL_PYTHON) +def unit(session): + """Run the unit test suite.""" + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.') + + session.run( + 'py.test', + '--quiet', + '--cov=google/cloud/vision_v1/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)) + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + session.install( + 'mypy', + 'types-requests', + 'types-protobuf' + ) + session.install('.') + session.run( + 'mypy', + '--explicit-package-bases', + 'google', + ) + + +@nox.session +def update_lower_bounds(session): + """Update lower bounds in constraints.txt to match setup.py""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'update', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + + +@nox.session +def check_lower_bounds(session): + """Check lower bounds in setup.py are reflected in constraints file""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'check', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install("sphinx==7.0.1", "alabaster", "recommonmark") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", BLACK_VERSION) + session.run( + "black", + "--check", + *BLACK_PATHS, + ) + session.run("flake8", "google", "tests", "samples") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *BLACK_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") diff --git a/owl-bot-staging/v1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json b/owl-bot-staging/v1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json new file mode 100644 index 00000000..e29e0ec2 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1.json @@ -0,0 +1,3784 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.vision.v1", + "version": "v1" + } + ], + "language": "PYTHON", + "name": "google-cloud-vision", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ImageAnnotatorAsyncClient.async_batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1.ImageAnnotator.AsyncBatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.AsyncBatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1.types.AsyncAnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "async_batch_annotate_files" + }, + "description": "Sample for AsyncBatchAnnotateFiles", + "file": "vision_v1_generated_image_annotator_async_batch_annotate_files_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_image_annotator_async_batch_annotate_files_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1.ImageAnnotatorClient.async_batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1.ImageAnnotator.AsyncBatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.AsyncBatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1.types.AsyncAnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "async_batch_annotate_files" + }, + "description": "Sample for AsyncBatchAnnotateFiles", + "file": "vision_v1_generated_image_annotator_async_batch_annotate_files_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_image_annotator_async_batch_annotate_files_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ImageAnnotatorAsyncClient.async_batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1.ImageAnnotator.AsyncBatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.AsyncBatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]" + }, + { + "name": "output_config", + "type": "google.cloud.vision_v1.types.OutputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "async_batch_annotate_images" + }, + "description": "Sample for AsyncBatchAnnotateImages", + "file": "vision_v1_generated_image_annotator_async_batch_annotate_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateImages_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_image_annotator_async_batch_annotate_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1.ImageAnnotatorClient.async_batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1.ImageAnnotator.AsyncBatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.AsyncBatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]" + }, + { + "name": "output_config", + "type": "google.cloud.vision_v1.types.OutputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "async_batch_annotate_images" + }, + "description": "Sample for AsyncBatchAnnotateImages", + "file": "vision_v1_generated_image_annotator_async_batch_annotate_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateImages_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_image_annotator_async_batch_annotate_images_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ImageAnnotatorAsyncClient.batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1.ImageAnnotator.BatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.BatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1.types.AnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.BatchAnnotateFilesResponse", + "shortName": "batch_annotate_files" + }, + "description": "Sample for BatchAnnotateFiles", + "file": "vision_v1_generated_image_annotator_batch_annotate_files_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ImageAnnotator_BatchAnnotateFiles_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_image_annotator_batch_annotate_files_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1.ImageAnnotatorClient.batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1.ImageAnnotator.BatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.BatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1.types.AnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.BatchAnnotateFilesResponse", + "shortName": "batch_annotate_files" + }, + "description": "Sample for BatchAnnotateFiles", + "file": "vision_v1_generated_image_annotator_batch_annotate_files_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ImageAnnotator_BatchAnnotateFiles_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_image_annotator_batch_annotate_files_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ImageAnnotatorAsyncClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1_generated_image_annotator_batch_annotate_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ImageAnnotator_BatchAnnotateImages_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_image_annotator_batch_annotate_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1.ImageAnnotatorClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1_generated_image_annotator_batch_annotate_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ImageAnnotator_BatchAnnotateImages_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_image_annotator_batch_annotate_images_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.add_product_to_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.AddProductToProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "AddProductToProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.AddProductToProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "add_product_to_product_set" + }, + "description": "Sample for AddProductToProductSet", + "file": "vision_v1_generated_product_search_add_product_to_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_AddProductToProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_add_product_to_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.add_product_to_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.AddProductToProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "AddProductToProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.AddProductToProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "add_product_to_product_set" + }, + "description": "Sample for AddProductToProductSet", + "file": "vision_v1_generated_product_search_add_product_to_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_AddProductToProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_add_product_to_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.create_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.CreateProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.CreateProductSetRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1.types.ProductSet" + }, + { + "name": "product_set_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ProductSet", + "shortName": "create_product_set" + }, + "description": "Sample for CreateProductSet", + "file": "vision_v1_generated_product_search_create_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_CreateProductSet_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_create_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.create_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.CreateProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.CreateProductSetRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1.types.ProductSet" + }, + { + "name": "product_set_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ProductSet", + "shortName": "create_product_set" + }, + "description": "Sample for CreateProductSet", + "file": "vision_v1_generated_product_search_create_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_CreateProductSet_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_create_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.create_product", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.CreateProduct", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.vision_v1.types.Product" + }, + { + "name": "product_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "vision_v1_generated_product_search_create_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_CreateProduct_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_create_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.create_product", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.CreateProduct", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.vision_v1.types.Product" + }, + { + "name": "product_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "vision_v1_generated_product_search_create_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_CreateProduct_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_create_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.create_reference_image", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.CreateReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.CreateReferenceImageRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "reference_image", + "type": "google.cloud.vision_v1.types.ReferenceImage" + }, + { + "name": "reference_image_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ReferenceImage", + "shortName": "create_reference_image" + }, + "description": "Sample for CreateReferenceImage", + "file": "vision_v1_generated_product_search_create_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_CreateReferenceImage_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_create_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.create_reference_image", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.CreateReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.CreateReferenceImageRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "reference_image", + "type": "google.cloud.vision_v1.types.ReferenceImage" + }, + { + "name": "reference_image_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ReferenceImage", + "shortName": "create_reference_image" + }, + "description": "Sample for CreateReferenceImage", + "file": "vision_v1_generated_product_search_create_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_CreateReferenceImage_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_create_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.delete_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.DeleteProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.DeleteProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product_set" + }, + "description": "Sample for DeleteProductSet", + "file": "vision_v1_generated_product_search_delete_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_DeleteProductSet_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_delete_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.delete_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.DeleteProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.DeleteProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product_set" + }, + "description": "Sample for DeleteProductSet", + "file": "vision_v1_generated_product_search_delete_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_DeleteProductSet_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_delete_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.delete_product", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.DeleteProduct", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.DeleteProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product" + }, + "description": "Sample for DeleteProduct", + "file": "vision_v1_generated_product_search_delete_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_DeleteProduct_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_delete_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.delete_product", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.DeleteProduct", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.DeleteProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product" + }, + "description": "Sample for DeleteProduct", + "file": "vision_v1_generated_product_search_delete_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_DeleteProduct_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_delete_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.delete_reference_image", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.DeleteReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.DeleteReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_reference_image" + }, + "description": "Sample for DeleteReferenceImage", + "file": "vision_v1_generated_product_search_delete_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_DeleteReferenceImage_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_delete_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.delete_reference_image", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.DeleteReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.DeleteReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_reference_image" + }, + "description": "Sample for DeleteReferenceImage", + "file": "vision_v1_generated_product_search_delete_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_DeleteReferenceImage_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_delete_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.get_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.GetProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.GetProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ProductSet", + "shortName": "get_product_set" + }, + "description": "Sample for GetProductSet", + "file": "vision_v1_generated_product_search_get_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_GetProductSet_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_get_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.get_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.GetProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.GetProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ProductSet", + "shortName": "get_product_set" + }, + "description": "Sample for GetProductSet", + "file": "vision_v1_generated_product_search_get_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_GetProductSet_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_get_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.get_product", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.GetProduct", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.GetProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "vision_v1_generated_product_search_get_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_GetProduct_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_get_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.get_product", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.GetProduct", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.GetProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "vision_v1_generated_product_search_get_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_GetProduct_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_get_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.get_reference_image", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.GetReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.GetReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ReferenceImage", + "shortName": "get_reference_image" + }, + "description": "Sample for GetReferenceImage", + "file": "vision_v1_generated_product_search_get_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_GetReferenceImage_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_get_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.get_reference_image", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.GetReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.GetReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ReferenceImage", + "shortName": "get_reference_image" + }, + "description": "Sample for GetReferenceImage", + "file": "vision_v1_generated_product_search_get_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_GetReferenceImage_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_get_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.import_product_sets", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ImportProductSets", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ImportProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ImportProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "input_config", + "type": "google.cloud.vision_v1.types.ImportProductSetsInputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "import_product_sets" + }, + "description": "Sample for ImportProductSets", + "file": "vision_v1_generated_product_search_import_product_sets_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ImportProductSets_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_import_product_sets_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.import_product_sets", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ImportProductSets", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ImportProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ImportProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "input_config", + "type": "google.cloud.vision_v1.types.ImportProductSetsInputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "import_product_sets" + }, + "description": "Sample for ImportProductSets", + "file": "vision_v1_generated_product_search_import_product_sets_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ImportProductSets_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_import_product_sets_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.list_product_sets", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ListProductSets", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ListProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.services.product_search.pagers.ListProductSetsAsyncPager", + "shortName": "list_product_sets" + }, + "description": "Sample for ListProductSets", + "file": "vision_v1_generated_product_search_list_product_sets_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ListProductSets_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_list_product_sets_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.list_product_sets", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ListProductSets", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ListProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.services.product_search.pagers.ListProductSetsPager", + "shortName": "list_product_sets" + }, + "description": "Sample for ListProductSets", + "file": "vision_v1_generated_product_search_list_product_sets_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ListProductSets_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_list_product_sets_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.list_products_in_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ListProductsInProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductsInProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ListProductsInProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.services.product_search.pagers.ListProductsInProductSetAsyncPager", + "shortName": "list_products_in_product_set" + }, + "description": "Sample for ListProductsInProductSet", + "file": "vision_v1_generated_product_search_list_products_in_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ListProductsInProductSet_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_list_products_in_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.list_products_in_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ListProductsInProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductsInProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ListProductsInProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.services.product_search.pagers.ListProductsInProductSetPager", + "shortName": "list_products_in_product_set" + }, + "description": "Sample for ListProductsInProductSet", + "file": "vision_v1_generated_product_search_list_products_in_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ListProductsInProductSet_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_list_products_in_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.list_products", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ListProducts", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ListProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.services.product_search.pagers.ListProductsAsyncPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "vision_v1_generated_product_search_list_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ListProducts_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_list_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.list_products", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ListProducts", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ListProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.services.product_search.pagers.ListProductsPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "vision_v1_generated_product_search_list_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ListProducts_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_list_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.list_reference_images", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ListReferenceImages", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListReferenceImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ListReferenceImagesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.services.product_search.pagers.ListReferenceImagesAsyncPager", + "shortName": "list_reference_images" + }, + "description": "Sample for ListReferenceImages", + "file": "vision_v1_generated_product_search_list_reference_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ListReferenceImages_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_list_reference_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.list_reference_images", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.ListReferenceImages", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListReferenceImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.ListReferenceImagesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.services.product_search.pagers.ListReferenceImagesPager", + "shortName": "list_reference_images" + }, + "description": "Sample for ListReferenceImages", + "file": "vision_v1_generated_product_search_list_reference_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_ListReferenceImages_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_list_reference_images_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.purge_products", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.PurgeProducts", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "PurgeProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.PurgeProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "purge_products" + }, + "description": "Sample for PurgeProducts", + "file": "vision_v1_generated_product_search_purge_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_PurgeProducts_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_purge_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.purge_products", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.PurgeProducts", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "PurgeProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.PurgeProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "purge_products" + }, + "description": "Sample for PurgeProducts", + "file": "vision_v1_generated_product_search_purge_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_PurgeProducts_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_purge_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.remove_product_from_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.RemoveProductFromProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "RemoveProductFromProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.RemoveProductFromProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "remove_product_from_product_set" + }, + "description": "Sample for RemoveProductFromProductSet", + "file": "vision_v1_generated_product_search_remove_product_from_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_RemoveProductFromProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_remove_product_from_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.remove_product_from_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.RemoveProductFromProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "RemoveProductFromProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.RemoveProductFromProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "remove_product_from_product_set" + }, + "description": "Sample for RemoveProductFromProductSet", + "file": "vision_v1_generated_product_search_remove_product_from_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_RemoveProductFromProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_remove_product_from_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.update_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.UpdateProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.UpdateProductSetRequest" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1.types.ProductSet" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ProductSet", + "shortName": "update_product_set" + }, + "description": "Sample for UpdateProductSet", + "file": "vision_v1_generated_product_search_update_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_UpdateProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_update_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.update_product_set", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.UpdateProductSet", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.UpdateProductSetRequest" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1.types.ProductSet" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.ProductSet", + "shortName": "update_product_set" + }, + "description": "Sample for UpdateProductSet", + "file": "vision_v1_generated_product_search_update_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_UpdateProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_update_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchAsyncClient.update_product", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.UpdateProduct", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.vision_v1.types.Product" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "vision_v1_generated_product_search_update_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_UpdateProduct_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_update_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1.ProductSearchClient.update_product", + "method": { + "fullName": "google.cloud.vision.v1.ProductSearch.UpdateProduct", + "service": { + "fullName": "google.cloud.vision.v1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.vision_v1.types.Product" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "vision_v1_generated_product_search_update_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1_generated_ProductSearch_UpdateProduct_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1_generated_product_search_update_product_sync.py" + } + ] +} diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_files_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_files_async.py new file mode 100644 index 00000000..dc692c88 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_files_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_files_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_files_sync.py new file mode 100644 index 00000000..f099599b --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_files_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_images_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_images_async.py new file mode 100644 index 00000000..c19eedb8 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_images_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_async_batch_annotate_images(): + # Create a client + client = vision_v1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1.AsyncBatchAnnotateImagesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_images(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateImages_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_images_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_images_sync.py new file mode 100644 index 00000000..49011b81 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_async_batch_annotate_images_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_async_batch_annotate_images(): + # Create a client + client = vision_v1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1.AsyncBatchAnnotateImagesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_images(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1_generated_ImageAnnotator_AsyncBatchAnnotateImages_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_files_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_files_async.py new file mode 100644 index 00000000..6f76174c --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_files_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ImageAnnotator_BatchAnnotateFiles_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_batch_annotate_files(): + # Create a client + client = vision_v1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1.BatchAnnotateFilesRequest( + ) + + # Make the request + response = await client.batch_annotate_files(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ImageAnnotator_BatchAnnotateFiles_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_files_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_files_sync.py new file mode 100644 index 00000000..f28a88cc --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_files_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ImageAnnotator_BatchAnnotateFiles_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_batch_annotate_files(): + # Create a client + client = vision_v1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1.BatchAnnotateFilesRequest( + ) + + # Make the request + response = client.batch_annotate_files(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ImageAnnotator_BatchAnnotateFiles_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_images_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_images_async.py new file mode 100644 index 00000000..30498490 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_images_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ImageAnnotator_BatchAnnotateImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_batch_annotate_images(): + # Create a client + client = vision_v1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ImageAnnotator_BatchAnnotateImages_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_images_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_images_sync.py new file mode 100644 index 00000000..84ee0d85 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_image_annotator_batch_annotate_images_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ImageAnnotator_BatchAnnotateImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_batch_annotate_images(): + # Create a client + client = vision_v1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ImageAnnotator_BatchAnnotateImages_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_add_product_to_product_set_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_add_product_to_product_set_async.py new file mode 100644 index 00000000..472a9fe6 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_add_product_to_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AddProductToProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_AddProductToProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_add_product_to_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.add_product_to_product_set(request=request) + + +# [END vision_v1_generated_ProductSearch_AddProductToProductSet_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_add_product_to_product_set_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_add_product_to_product_set_sync.py new file mode 100644 index 00000000..ddd7bb49 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_add_product_to_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AddProductToProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_AddProductToProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_add_product_to_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.add_product_to_product_set(request=request) + + +# [END vision_v1_generated_ProductSearch_AddProductToProductSet_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_async.py new file mode 100644 index 00000000..eb4df858 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_CreateProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_create_product(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_CreateProduct_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_set_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_set_async.py new file mode 100644 index 00000000..ddf8a78c --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_set_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_CreateProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_create_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_CreateProductSet_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_set_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_set_sync.py new file mode 100644 index 00000000..ace1cbba --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_set_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_CreateProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_create_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_CreateProductSet_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_sync.py new file mode 100644 index 00000000..31c5df92 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_product_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_CreateProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_create_product(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_CreateProduct_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_reference_image_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_reference_image_async.py new file mode 100644 index 00000000..016941bc --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_reference_image_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_CreateReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_create_reference_image(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + reference_image = vision_v1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = await client.create_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_CreateReferenceImage_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_reference_image_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_reference_image_sync.py new file mode 100644 index 00000000..6cf61308 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_create_reference_image_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_CreateReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_create_reference_image(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + reference_image = vision_v1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = client.create_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_CreateReferenceImage_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_async.py new file mode 100644 index 00000000..3393c32e --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_DeleteProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_delete_product(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + +# [END vision_v1_generated_ProductSearch_DeleteProduct_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_set_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_set_async.py new file mode 100644 index 00000000..e7625963 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_set_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_DeleteProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_delete_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + await client.delete_product_set(request=request) + + +# [END vision_v1_generated_ProductSearch_DeleteProductSet_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_set_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_set_sync.py new file mode 100644 index 00000000..bb3b1bde --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_set_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_DeleteProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_delete_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + client.delete_product_set(request=request) + + +# [END vision_v1_generated_ProductSearch_DeleteProductSet_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_sync.py new file mode 100644 index 00000000..a5707d11 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_product_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_DeleteProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_delete_product(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + +# [END vision_v1_generated_ProductSearch_DeleteProduct_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_reference_image_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_reference_image_async.py new file mode 100644 index 00000000..14304e2e --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_reference_image_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_DeleteReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_delete_reference_image(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + await client.delete_reference_image(request=request) + + +# [END vision_v1_generated_ProductSearch_DeleteReferenceImage_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_reference_image_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_reference_image_sync.py new file mode 100644 index 00000000..931c7f5f --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_delete_reference_image_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_DeleteReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_delete_reference_image(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + client.delete_reference_image(request=request) + + +# [END vision_v1_generated_ProductSearch_DeleteReferenceImage_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_async.py new file mode 100644 index 00000000..2149fa43 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_GetProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_get_product(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_GetProduct_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_set_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_set_async.py new file mode 100644 index 00000000..321da464 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_set_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_GetProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_get_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_GetProductSet_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_set_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_set_sync.py new file mode 100644 index 00000000..7fe1eebd --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_set_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_GetProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_get_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = client.get_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_GetProductSet_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_sync.py new file mode 100644 index 00000000..16dc9122 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_product_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_GetProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_get_product(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_GetProduct_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_reference_image_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_reference_image_async.py new file mode 100644 index 00000000..f1e4ae0d --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_reference_image_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_GetReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_get_reference_image(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = await client.get_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_GetReferenceImage_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_reference_image_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_reference_image_sync.py new file mode 100644 index 00000000..e9c09ead --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_get_reference_image_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_GetReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_get_reference_image(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = client.get_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_GetReferenceImage_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_import_product_sets_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_import_product_sets_async.py new file mode 100644 index 00000000..8ff5e371 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_import_product_sets_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ImportProductSets_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_import_product_sets(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_ImportProductSets_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_import_product_sets_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_import_product_sets_sync.py new file mode 100644 index 00000000..90ff19ca --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_import_product_sets_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ImportProductSets_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_import_product_sets(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_ImportProductSets_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_product_sets_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_product_sets_async.py new file mode 100644 index 00000000..20a5ce78 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_product_sets_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ListProductSets_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_list_product_sets(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1_generated_ProductSearch_ListProductSets_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_product_sets_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_product_sets_sync.py new file mode 100644 index 00000000..9967db0f --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_product_sets_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ListProductSets_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_list_product_sets(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1_generated_ProductSearch_ListProductSets_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_async.py new file mode 100644 index 00000000..2e1ecc9a --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ListProducts_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_list_products(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1_generated_ProductSearch_ListProducts_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_in_product_set_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_in_product_set_async.py new file mode 100644 index 00000000..4458f5c3 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_in_product_set_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductsInProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ListProductsInProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_list_products_in_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1_generated_ProductSearch_ListProductsInProductSet_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_in_product_set_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_in_product_set_sync.py new file mode 100644 index 00000000..9cce45b3 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_in_product_set_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductsInProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ListProductsInProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_list_products_in_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1_generated_ProductSearch_ListProductsInProductSet_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_sync.py new file mode 100644 index 00000000..7bad5bdd --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_products_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ListProducts_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_list_products(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1_generated_ProductSearch_ListProducts_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_reference_images_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_reference_images_async.py new file mode 100644 index 00000000..03f2d273 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_reference_images_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListReferenceImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ListReferenceImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_list_reference_images(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1_generated_ProductSearch_ListReferenceImages_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_reference_images_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_reference_images_sync.py new file mode 100644 index 00000000..ba6ffed0 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_list_reference_images_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListReferenceImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_ListReferenceImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_list_reference_images(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1_generated_ProductSearch_ListReferenceImages_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_purge_products_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_purge_products_async.py new file mode 100644 index 00000000..224ef338 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_purge_products_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for PurgeProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_PurgeProducts_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_purge_products(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.PurgeProductsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.purge_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_PurgeProducts_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_purge_products_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_purge_products_sync.py new file mode 100644 index 00000000..80cc88bd --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_purge_products_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for PurgeProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_PurgeProducts_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_purge_products(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.PurgeProductsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.purge_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_PurgeProducts_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_remove_product_from_product_set_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_remove_product_from_product_set_async.py new file mode 100644 index 00000000..9171005c --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_remove_product_from_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RemoveProductFromProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_RemoveProductFromProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.remove_product_from_product_set(request=request) + + +# [END vision_v1_generated_ProductSearch_RemoveProductFromProductSet_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_remove_product_from_product_set_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_remove_product_from_product_set_sync.py new file mode 100644 index 00000000..9d403c9d --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_remove_product_from_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RemoveProductFromProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_RemoveProductFromProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.remove_product_from_product_set(request=request) + + +# [END vision_v1_generated_ProductSearch_RemoveProductFromProductSet_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_async.py new file mode 100644 index 00000000..003b7cab --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_UpdateProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_update_product(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.UpdateProductRequest( + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_UpdateProduct_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_set_async.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_set_async.py new file mode 100644 index 00000000..5b29a50d --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_UpdateProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +async def sample_update_product_set(): + # Create a client + client = vision_v1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1.UpdateProductSetRequest( + ) + + # Make the request + response = await client.update_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_UpdateProductSet_async] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_set_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_set_sync.py new file mode 100644 index 00000000..c67ac175 --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_UpdateProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_update_product_set(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.UpdateProductSetRequest( + ) + + # Make the request + response = client.update_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_UpdateProductSet_sync] diff --git a/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_sync.py b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_sync.py new file mode 100644 index 00000000..8784a82b --- /dev/null +++ b/owl-bot-staging/v1/samples/generated_samples/vision_v1_generated_product_search_update_product_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1_generated_ProductSearch_UpdateProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1 + + +def sample_update_product(): + # Create a client + client = vision_v1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1.UpdateProductRequest( + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1_generated_ProductSearch_UpdateProduct_sync] diff --git a/owl-bot-staging/v1/scripts/fixup_vision_v1_keywords.py b/owl-bot-staging/v1/scripts/fixup_vision_v1_keywords.py new file mode 100644 index 00000000..c1c3c346 --- /dev/null +++ b/owl-bot-staging/v1/scripts/fixup_vision_v1_keywords.py @@ -0,0 +1,198 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class visionCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'add_product_to_product_set': ('name', 'product', ), + 'async_batch_annotate_files': ('requests', 'parent', ), + 'async_batch_annotate_images': ('requests', 'output_config', 'parent', ), + 'batch_annotate_files': ('requests', 'parent', ), + 'batch_annotate_images': ('requests', 'parent', ), + 'create_product': ('parent', 'product', 'product_id', ), + 'create_product_set': ('parent', 'product_set', 'product_set_id', ), + 'create_reference_image': ('parent', 'reference_image', 'reference_image_id', ), + 'delete_product': ('name', ), + 'delete_product_set': ('name', ), + 'delete_reference_image': ('name', ), + 'get_product': ('name', ), + 'get_product_set': ('name', ), + 'get_reference_image': ('name', ), + 'import_product_sets': ('parent', 'input_config', ), + 'list_products': ('parent', 'page_size', 'page_token', ), + 'list_product_sets': ('parent', 'page_size', 'page_token', ), + 'list_products_in_product_set': ('name', 'page_size', 'page_token', ), + 'list_reference_images': ('parent', 'page_size', 'page_token', ), + 'purge_products': ('parent', 'product_set_purge_config', 'delete_orphan_products', 'force', ), + 'remove_product_from_product_set': ('name', 'product', ), + 'update_product': ('product', 'update_mask', ), + 'update_product_set': ('product_set', 'update_mask', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=visionCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the vision client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/owl-bot-staging/v1/setup.py b/owl-bot-staging/v1/setup.py new file mode 100644 index 00000000..7525c907 --- /dev/null +++ b/owl-bot-staging/v1/setup.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import io +import os + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-cloud-vision' + + +description = "Google Cloud Vision API client library" + +version = {} +with open(os.path.join(package_root, 'google/cloud/vision/gapic_version.py')) as fp: + exec(fp.read(), version) +version = version["__version__"] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.0, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "proto-plus >= 1.22.0, <2.0.0dev", + "proto-plus >= 1.22.2, <2.0.0dev; python_version>='3.11'", + "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/python-vision" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.PEP420PackageFinder.find() + if package.startswith("google") +] + +namespaces = ["google", "google.cloud"] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + namespace_packages=namespaces, + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/v1/testing/constraints-3.10.txt b/owl-bot-staging/v1/testing/constraints-3.10.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1/testing/constraints-3.11.txt b/owl-bot-staging/v1/testing/constraints-3.11.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1/testing/constraints-3.12.txt b/owl-bot-staging/v1/testing/constraints-3.12.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1/testing/constraints-3.7.txt b/owl-bot-staging/v1/testing/constraints-3.7.txt new file mode 100644 index 00000000..6c44adfe --- /dev/null +++ b/owl-bot-staging/v1/testing/constraints-3.7.txt @@ -0,0 +1,9 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file. +# Pin the version to the lower bound. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", +# Then this file should have google-cloud-foo==1.14.0 +google-api-core==1.34.0 +proto-plus==1.22.0 +protobuf==3.19.5 diff --git a/owl-bot-staging/v1/testing/constraints-3.8.txt b/owl-bot-staging/v1/testing/constraints-3.8.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1/testing/constraints-3.9.txt b/owl-bot-staging/v1/testing/constraints-3.9.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1/tests/__init__.py b/owl-bot-staging/v1/tests/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1/tests/unit/__init__.py b/owl-bot-staging/v1/tests/unit/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1/tests/unit/gapic/__init__.py b/owl-bot-staging/v1/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1/tests/unit/gapic/vision_v1/__init__.py b/owl-bot-staging/v1/tests/unit/gapic/vision_v1/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1/tests/unit/gapic/vision_v1/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1/tests/unit/gapic/vision_v1/test_image_annotator.py b/owl-bot-staging/v1/tests/unit/gapic/vision_v1/test_image_annotator.py new file mode 100644 index 00000000..0d164afd --- /dev/null +++ b/owl-bot-staging/v1/tests/unit/gapic/vision_v1/test_image_annotator.py @@ -0,0 +1,2900 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule +from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.vision_v1.services.image_annotator import ImageAnnotatorAsyncClient +from google.cloud.vision_v1.services.image_annotator import ImageAnnotatorClient +from google.cloud.vision_v1.services.image_annotator import transports +from google.cloud.vision_v1.types import geometry +from google.cloud.vision_v1.types import image_annotator +from google.cloud.vision_v1.types import product_search +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.type import latlng_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ImageAnnotatorClient._get_default_mtls_endpoint(None) is None + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ImageAnnotatorGrpcTransport, "grpc"), + (transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +def test_image_annotator_client_get_transport_class(): + transport = ImageAnnotatorClient.get_transport_class() + available_transports = [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorRestTransport, + ] + assert transport in available_transports + + transport = ImageAnnotatorClient.get_transport_class("grpc") + assert transport == transports.ImageAnnotatorGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "true"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "false"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "false"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_image_annotator_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + ImageAnnotatorClient, ImageAnnotatorAsyncClient +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", None), +]) +def test_image_annotator_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_image_annotator_client_client_options_from_dict(): + with mock.patch('google.cloud.vision_v1.services.image_annotator.transports.ImageAnnotatorGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ImageAnnotatorClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_image_annotator_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=None, + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse( + ) + response = client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + client.batch_annotate_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + +@pytest.mark.asyncio +async def test_batch_annotate_images_async(transport: str = 'grpc_asyncio', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse( + )) + response = await client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +@pytest.mark.asyncio +async def test_batch_annotate_images_async_from_dict(): + await test_batch_annotate_images_async(request_type=dict) + + +def test_batch_annotate_images_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + + +def test_batch_annotate_images_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateFilesRequest, + dict, +]) +def test_batch_annotate_files(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateFilesResponse( + ) + response = client.batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateFilesResponse) + + +def test_batch_annotate_files_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + client.batch_annotate_files() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateFilesRequest() + +@pytest.mark.asyncio +async def test_batch_annotate_files_async(transport: str = 'grpc_asyncio', request_type=image_annotator.BatchAnnotateFilesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateFilesResponse( + )) + response = await client.batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateFilesResponse) + + +@pytest.mark.asyncio +async def test_batch_annotate_files_async_from_dict(): + await test_batch_annotate_files_async(request_type=dict) + + +def test_batch_annotate_files_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateFilesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_annotate_files( + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + + +def test_batch_annotate_files_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_files( + image_annotator.BatchAnnotateFilesRequest(), + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + +@pytest.mark.asyncio +async def test_batch_annotate_files_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateFilesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateFilesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_annotate_files( + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_annotate_files_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_annotate_files( + image_annotator.BatchAnnotateFilesRequest(), + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateImagesRequest, + dict, +]) +def test_async_batch_annotate_images(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.async_batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_async_batch_annotate_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + client.async_batch_annotate_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateImagesRequest() + +@pytest.mark.asyncio +async def test_async_batch_annotate_images_async(transport: str = 'grpc_asyncio', request_type=image_annotator.AsyncBatchAnnotateImagesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.async_batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_async_batch_annotate_images_async_from_dict(): + await test_async_batch_annotate_images_async(request_type=dict) + + +def test_async_batch_annotate_images_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.async_batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + arg = args[0].output_config + mock_val = image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')) + assert arg == mock_val + + +def test_async_batch_annotate_images_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_images( + image_annotator.AsyncBatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + +@pytest.mark.asyncio +async def test_async_batch_annotate_images_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.async_batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + arg = args[0].output_config + mock_val = image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_async_batch_annotate_images_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.async_batch_annotate_images( + image_annotator.AsyncBatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateFilesRequest, + dict, +]) +def test_async_batch_annotate_files(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.async_batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_async_batch_annotate_files_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + client.async_batch_annotate_files() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_async(transport: str = 'grpc_asyncio', request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.async_batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_async_from_dict(): + await test_async_batch_annotate_files_async(request_type=dict) + + +def test_async_batch_annotate_files_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.async_batch_annotate_files( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + + +def test_async_batch_annotate_files_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.async_batch_annotate_files( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_annotate_images(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_rest_required_fields(request_type=image_annotator.BatchAnnotateImagesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_annotate_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_annotate_images_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_annotate_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_annotate_images_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_batch_annotate_images") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_batch_annotate_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.BatchAnnotateImagesRequest.pb(image_annotator.BatchAnnotateImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = image_annotator.BatchAnnotateImagesResponse.to_json(image_annotator.BatchAnnotateImagesResponse()) + + request = image_annotator.BatchAnnotateImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = image_annotator.BatchAnnotateImagesResponse() + + client.batch_annotate_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_annotate_images_rest_bad_request(transport: str = 'rest', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.batch_annotate_images(request) + + +def test_batch_annotate_images_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_annotate_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/images:annotate" % client.transport._host, args[1]) + + +def test_batch_annotate_images_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +def test_batch_annotate_images_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateFilesRequest, + dict, +]) +def test_batch_annotate_files_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateFilesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateFilesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_annotate_files(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateFilesResponse) + + +def test_batch_annotate_files_rest_required_fields(request_type=image_annotator.BatchAnnotateFilesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateFilesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateFilesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_annotate_files(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_annotate_files_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_annotate_files._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_annotate_files_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_batch_annotate_files") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_batch_annotate_files") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.BatchAnnotateFilesRequest.pb(image_annotator.BatchAnnotateFilesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = image_annotator.BatchAnnotateFilesResponse.to_json(image_annotator.BatchAnnotateFilesResponse()) + + request = image_annotator.BatchAnnotateFilesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = image_annotator.BatchAnnotateFilesResponse() + + client.batch_annotate_files(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_annotate_files_rest_bad_request(transport: str = 'rest', request_type=image_annotator.BatchAnnotateFilesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.batch_annotate_files(request) + + +def test_batch_annotate_files_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateFilesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateFilesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_annotate_files(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/files:annotate" % client.transport._host, args[1]) + + +def test_batch_annotate_files_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_files( + image_annotator.BatchAnnotateFilesRequest(), + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +def test_batch_annotate_files_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateImagesRequest, + dict, +]) +def test_async_batch_annotate_images_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.async_batch_annotate_images(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_async_batch_annotate_images_rest_required_fields(request_type=image_annotator.AsyncBatchAnnotateImagesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.async_batch_annotate_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_async_batch_annotate_images_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.async_batch_annotate_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", "outputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_async_batch_annotate_images_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_async_batch_annotate_images") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_async_batch_annotate_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.AsyncBatchAnnotateImagesRequest.pb(image_annotator.AsyncBatchAnnotateImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = image_annotator.AsyncBatchAnnotateImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.async_batch_annotate_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_async_batch_annotate_images_rest_bad_request(transport: str = 'rest', request_type=image_annotator.AsyncBatchAnnotateImagesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.async_batch_annotate_images(request) + + +def test_async_batch_annotate_images_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.async_batch_annotate_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/images:asyncBatchAnnotate" % client.transport._host, args[1]) + + +def test_async_batch_annotate_images_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_images( + image_annotator.AsyncBatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + + +def test_async_batch_annotate_images_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateFilesRequest, + dict, +]) +def test_async_batch_annotate_files_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.async_batch_annotate_files(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_async_batch_annotate_files_rest_required_fields(request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.async_batch_annotate_files(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_async_batch_annotate_files_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.async_batch_annotate_files._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_async_batch_annotate_files_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_async_batch_annotate_files") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_async_batch_annotate_files") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.AsyncBatchAnnotateFilesRequest.pb(image_annotator.AsyncBatchAnnotateFilesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = image_annotator.AsyncBatchAnnotateFilesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.async_batch_annotate_files(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_async_batch_annotate_files_rest_bad_request(transport: str = 'rest', request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.async_batch_annotate_files(request) + + +def test_async_batch_annotate_files_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.async_batch_annotate_files(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/files:asyncBatchAnnotate" % client.transport._host, args[1]) + + +def test_async_batch_annotate_files_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +def test_async_batch_annotate_files_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ImageAnnotatorClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "rest", +]) +def test_transport_kind(transport_name): + transport = ImageAnnotatorClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ImageAnnotatorGrpcTransport, + ) + +def test_image_annotator_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_image_annotator_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.vision_v1.services.image_annotator.transports.ImageAnnotatorTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'batch_annotate_images', + 'batch_annotate_files', + 'async_batch_annotate_images', + 'async_batch_annotate_files', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_image_annotator_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.vision_v1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id="octopus", + ) + + +def test_image_annotator_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.vision_v1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport() + adc.assert_called_once() + + +def test_image_annotator_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ImageAnnotatorClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + ], +) +def test_image_annotator_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-vision',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, + ], +) +def test_image_annotator_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ImageAnnotatorGrpcTransport, grpc_helpers), + (transports.ImageAnnotatorGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_image_annotator_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=["1", "2"], + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_image_annotator_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel") as mock_configure_mtls_channel: + transports.ImageAnnotatorRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_image_annotator_rest_lro_client(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_no_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_with_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_image_annotator_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ImageAnnotatorClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ImageAnnotatorClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.batch_annotate_images._session + session2 = client2.transport.batch_annotate_images._session + assert session1 != session2 + session1 = client1.transport.batch_annotate_files._session + session2 = client2.transport.batch_annotate_files._session + assert session1 != session2 + session1 = client1.transport.async_batch_annotate_images._session + session2 = client2.transport.async_batch_annotate_images._session + assert session1 != session2 + session1 = client1.transport.async_batch_annotate_files._session + session2 = client2.transport.async_batch_annotate_files._session + assert session1 != session2 +def test_image_annotator_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_image_annotator_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_image_annotator_grpc_lro_client(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_image_annotator_grpc_lro_async_client(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_path(): + project = "squid" + location = "clam" + product = "whelk" + expected = "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + actual = ImageAnnotatorClient.product_path(project, location, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "octopus", + "location": "oyster", + "product": "nudibranch", + } + path = ImageAnnotatorClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_product_path(path) + assert expected == actual + +def test_product_set_path(): + project = "cuttlefish" + location = "mussel" + product_set = "winkle" + expected = "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + actual = ImageAnnotatorClient.product_set_path(project, location, product_set) + assert expected == actual + + +def test_parse_product_set_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "product_set": "abalone", + } + path = ImageAnnotatorClient.product_set_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_product_set_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ImageAnnotatorClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = ImageAnnotatorClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder, ) + actual = ImageAnnotatorClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = ImageAnnotatorClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ImageAnnotatorClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = ImageAnnotatorClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project, ) + actual = ImageAnnotatorClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = ImageAnnotatorClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ImageAnnotatorClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = ImageAnnotatorClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + transport_class = ImageAnnotatorClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/owl-bot-staging/v1/tests/unit/gapic/vision_v1/test_product_search.py b/owl-bot-staging/v1/tests/unit/gapic/vision_v1/test_product_search.py new file mode 100644 index 00000000..dd3e1577 --- /dev/null +++ b/owl-bot-staging/v1/tests/unit/gapic/vision_v1/test_product_search.py @@ -0,0 +1,11710 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule +from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.vision_v1.services.product_search import ProductSearchAsyncClient +from google.cloud.vision_v1.services.product_search import ProductSearchClient +from google.cloud.vision_v1.services.product_search import pagers +from google.cloud.vision_v1.services.product_search import transports +from google.cloud.vision_v1.types import geometry +from google.cloud.vision_v1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ProductSearchClient._get_default_mtls_endpoint(None) is None + assert ProductSearchClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductSearchClient, "grpc"), + (ProductSearchAsyncClient, "grpc_asyncio"), + (ProductSearchClient, "rest"), +]) +def test_product_search_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ProductSearchGrpcTransport, "grpc"), + (transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ProductSearchRestTransport, "rest"), +]) +def test_product_search_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductSearchClient, "grpc"), + (ProductSearchAsyncClient, "grpc_asyncio"), + (ProductSearchClient, "rest"), +]) +def test_product_search_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +def test_product_search_client_get_transport_class(): + transport = ProductSearchClient.get_transport_class() + available_transports = [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchRestTransport, + ] + assert transport in available_transports + + transport = ProductSearchClient.get_transport_class("grpc") + assert transport == transports.ProductSearchGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest"), +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +def test_product_search_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ProductSearchClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ProductSearchClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", "true"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", "false"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", "true"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", "false"), +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_product_search_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + ProductSearchClient, ProductSearchAsyncClient +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +def test_product_search_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest"), +]) +def test_product_search_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", grpc_helpers), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", None), +]) +def test_product_search_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_product_search_client_client_options_from_dict(): + with mock.patch('google.cloud.vision_v1.services.product_search.transports.ProductSearchGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ProductSearchClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", grpc_helpers), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_product_search_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=None, + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductSetRequest, + dict, +]) +def test_create_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_create_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + client.create_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + +@pytest.mark.asyncio +async def test_create_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_create_product_set_async_from_dict(): + await test_create_product_set_async(request_type=dict) + + +def test_create_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductSetRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductSetRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_product_set( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].product_set_id + mock_val = 'product_set_id_value' + assert arg == mock_val + + +def test_create_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_product_set( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].product_set_id + mock_val = 'product_set_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductSetsRequest, + dict, +]) +def test_list_product_sets(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_product_sets_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + client.list_product_sets() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + +@pytest.mark.asyncio +async def test_list_product_sets_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductSetsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_product_sets_async_from_dict(): + await test_list_product_sets_async(request_type=dict) + + +def test_list_product_sets_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + call.return_value = product_search_service.ListProductSetsResponse() + client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_product_sets_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse()) + await client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_product_sets_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_product_sets( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_product_sets_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_product_sets_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_product_sets( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_product_sets_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + + +def test_list_product_sets_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_product_sets(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in results) +def test_list_product_sets_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + pages = list(client.list_product_sets(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_product_sets_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_product_sets(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_product_sets_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_product_sets(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductSetRequest, + dict, +]) +def test_get_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_get_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + client.get_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + +@pytest.mark.asyncio +async def test_get_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_get_product_set_async_from_dict(): + await test_get_product_set_async(request_type=dict) + + +def test_get_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductSetRequest, + dict, +]) +def test_update_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + client.update_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + +@pytest.mark.asyncio +async def test_update_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.UpdateProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_update_product_set_async_from_dict(): + await test_update_product_set_async(request_type=dict) + + +def test_update_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductSetRequest() + + request.product_set.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product_set.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductSetRequest() + + request.product_set.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product_set.name=name_value', + ) in kw['metadata'] + + +def test_update_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product_set( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_update_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_product_set( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_update_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductSetRequest, + dict, +]) +def test_delete_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + client.delete_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + +@pytest.mark.asyncio +async def test_delete_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_product_set_async_from_dict(): + await test_delete_product_set_async(request_type=dict) + + +def test_delete_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + call.return_value = None + client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductRequest, + dict, +]) +def test_create_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_create_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + client.create_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + +@pytest.mark.asyncio +async def test_create_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_create_product_async_from_dict(): + await test_create_product_async(request_type=dict) + + +def test_create_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_product( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].product_id + mock_val = 'product_id_value' + assert arg == mock_val + + +def test_create_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_product( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].product_id + mock_val = 'product_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsRequest, + dict, +]) +def test_list_products(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + client.list_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + +@pytest.mark.asyncio +async def test_list_products_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_products_async_from_dict(): + await test_list_products_async(request_type=dict) + + +def test_list_products_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + call.return_value = product_search_service.ListProductsResponse() + client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_products_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse()) + await client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_products_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_products_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_products_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_products_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_products(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) +def test_list_products_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = list(client.list_products(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_products_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_products(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_products(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductRequest, + dict, +]) +def test_get_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_get_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + client.get_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + +@pytest.mark.asyncio +async def test_get_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_get_product_async_from_dict(): + await test_get_product_async(request_type=dict) + + +def test_get_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductRequest, + dict, +]) +def test_update_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_update_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + client.update_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + +@pytest.mark.asyncio +async def test_update_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.UpdateProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_update_product_async_from_dict(): + await test_update_product_async(request_type=dict) + + +def test_update_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductRequest() + + request.product.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductRequest() + + request.product.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product.name=name_value', + ) in kw['metadata'] + + +def test_update_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_update_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_product( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_update_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductRequest, + dict, +]) +def test_delete_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + client.delete_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + +@pytest.mark.asyncio +async def test_delete_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_product_async_from_dict(): + await test_delete_product_async(request_type=dict) + + +def test_delete_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + call.return_value = None + client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateReferenceImageRequest, + dict, +]) +def test_create_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + response = client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_create_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + client.create_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + +@pytest.mark.asyncio +async def test_create_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + )) + response = await client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +@pytest.mark.asyncio +async def test_create_reference_image_async_from_dict(): + await test_create_reference_image_async(request_type=dict) + + +def test_create_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateReferenceImageRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + call.return_value = product_search_service.ReferenceImage() + client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateReferenceImageRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + await client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_reference_image( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].reference_image + mock_val = product_search_service.ReferenceImage(name='name_value') + assert arg == mock_val + arg = args[0].reference_image_id + mock_val = 'reference_image_id_value' + assert arg == mock_val + + +def test_create_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + +@pytest.mark.asyncio +async def test_create_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_reference_image( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].reference_image + mock_val = product_search_service.ReferenceImage(name='name_value') + assert arg == mock_val + arg = args[0].reference_image_id + mock_val = 'reference_image_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteReferenceImageRequest, + dict, +]) +def test_delete_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + client.delete_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + +@pytest.mark.asyncio +async def test_delete_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_reference_image_async_from_dict(): + await test_delete_reference_image_async(request_type=dict) + + +def test_delete_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + call.return_value = None + client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListReferenceImagesRequest, + dict, +]) +def test_list_reference_images(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + ) + response = client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +def test_list_reference_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + client.list_reference_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + +@pytest.mark.asyncio +async def test_list_reference_images_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListReferenceImagesRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + )) + response = await client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesAsyncPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_reference_images_async_from_dict(): + await test_list_reference_images_async(request_type=dict) + + +def test_list_reference_images_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListReferenceImagesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + call.return_value = product_search_service.ListReferenceImagesResponse() + client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_reference_images_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListReferenceImagesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse()) + await client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_reference_images_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_reference_images( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_reference_images_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_reference_images_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_reference_images( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_reference_images_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + + +def test_list_reference_images_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_reference_images(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in results) +def test_list_reference_images_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + pages = list(client.list_reference_images(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_reference_images_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_reference_images(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_reference_images_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_reference_images(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetReferenceImageRequest, + dict, +]) +def test_get_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + response = client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_get_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + client.get_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + +@pytest.mark.asyncio +async def test_get_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + )) + response = await client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +@pytest.mark.asyncio +async def test_get_reference_image_async_from_dict(): + await test_get_reference_image_async(request_type=dict) + + +def test_get_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + call.return_value = product_search_service.ReferenceImage() + client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + await client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.AddProductToProductSetRequest, + dict, +]) +def test_add_product_to_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_add_product_to_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + client.add_product_to_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + +@pytest.mark.asyncio +async def test_add_product_to_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.AddProductToProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_add_product_to_product_set_async_from_dict(): + await test_add_product_to_product_set_async(request_type=dict) + + +def test_add_product_to_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.AddProductToProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + call.return_value = None + client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_product_to_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.AddProductToProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_add_product_to_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.add_product_to_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_product_to_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_product_to_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.add_product_to_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_product_to_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.RemoveProductFromProductSetRequest, + dict, +]) +def test_remove_product_from_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_remove_product_from_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + client.remove_product_from_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.RemoveProductFromProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_async_from_dict(): + await test_remove_product_from_product_set_async(request_type=dict) + + +def test_remove_product_from_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.RemoveProductFromProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + call.return_value = None + client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.RemoveProductFromProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_remove_product_from_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.remove_product_from_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_product_from_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.remove_product_from_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsInProductSetRequest, + dict, +]) +def test_list_products_in_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + ) + response = client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_in_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + client.list_products_in_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductsInProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_from_dict(): + await test_list_products_in_product_set_async(request_type=dict) + + +def test_list_products_in_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsInProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + call.return_value = product_search_service.ListProductsInProductSetResponse() + client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsInProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse()) + await client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_list_products_in_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_products_in_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_list_products_in_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_list_products_in_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_products_in_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_products_in_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + + +def test_list_products_in_product_set_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('name', ''), + )), + ) + pager = client.list_products_in_product_set(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) +def test_list_products_in_product_set_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = list(client.list_products_in_product_set(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_products_in_product_set(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_products_in_product_set(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.ImportProductSetsRequest, + dict, +]) +def test_import_product_sets(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_product_sets_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + client.import_product_sets() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + +@pytest.mark.asyncio +async def test_import_product_sets_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ImportProductSetsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_product_sets_async_from_dict(): + await test_import_product_sets_async(request_type=dict) + + +def test_import_product_sets_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ImportProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_import_product_sets_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ImportProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_import_product_sets_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.import_product_sets( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].input_config + mock_val = product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')) + assert arg == mock_val + + +def test_import_product_sets_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + +@pytest.mark.asyncio +async def test_import_product_sets_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.import_product_sets( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].input_config + mock_val = product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_import_product_sets_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.PurgeProductsRequest, + dict, +]) +def test_purge_products(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.purge_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.PurgeProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_purge_products_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + client.purge_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.PurgeProductsRequest() + +@pytest.mark.asyncio +async def test_purge_products_async(transport: str = 'grpc_asyncio', request_type=product_search_service.PurgeProductsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.purge_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.PurgeProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_purge_products_async_from_dict(): + await test_purge_products_async(request_type=dict) + + +def test_purge_products_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.PurgeProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.purge_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_purge_products_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.PurgeProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.purge_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_purge_products_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.purge_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_purge_products_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.purge_products( + product_search_service.PurgeProductsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_purge_products_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.purge_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_purge_products_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.purge_products( + product_search_service.PurgeProductsRequest(), + parent='parent_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductSetRequest, + dict, +]) +def test_create_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request_init["product_set"] = {'name': 'name_value', 'display_name': 'display_name_value', 'index_time': {'seconds': 751, 'nanos': 543}, 'index_error': {'code': 411, 'message': 'message_value', 'details': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}]}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateProductSetRequest.meta.fields["product_set"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product_set"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product_set"][field])): + del request_init["product_set"][field][i][subfield] + else: + del request_init["product_set"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_create_product_set_rest_required_fields(request_type=product_search_service.CreateProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("product_set_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productSetId", )) & set(("parent", "productSet", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateProductSetRequest.pb(product_search_service.CreateProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.CreateProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.create_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_product_set(request) + + +def test_create_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*/locations/*}/productSets" % client.transport._host, args[1]) + + +def test_create_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + +def test_create_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductSetsRequest, + dict, +]) +def test_list_product_sets_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_product_sets(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_product_sets_rest_required_fields(request_type=product_search_service.ListProductSetsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_product_sets._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_product_sets(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_product_sets_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_product_sets._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_product_sets_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_product_sets") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_product_sets") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductSetsRequest.pb(product_search_service.ListProductSetsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductSetsResponse.to_json(product_search_service.ListProductSetsResponse()) + + request = product_search_service.ListProductSetsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductSetsResponse() + + client.list_product_sets(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_product_sets_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductSetsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_product_sets(request) + + +def test_list_product_sets_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_product_sets(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*/locations/*}/productSets" % client.transport._host, args[1]) + + +def test_list_product_sets_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + + +def test_list_product_sets_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductSetsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + pager = client.list_product_sets(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in results) + + pages = list(client.list_product_sets(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductSetRequest, + dict, +]) +def test_get_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_get_product_set_rest_required_fields(request_type=product_search_service.GetProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetProductSetRequest.pb(product_search_service.GetProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.GetProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.get_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_product_set(request) + + +def test_get_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_get_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + + +def test_get_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductSetRequest, + dict, +]) +def test_update_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + request_init["product_set"] = {'name': 'projects/sample1/locations/sample2/productSets/sample3', 'display_name': 'display_name_value', 'index_time': {'seconds': 751, 'nanos': 543}, 'index_error': {'code': 411, 'message': 'message_value', 'details': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}]}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.UpdateProductSetRequest.meta.fields["product_set"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product_set"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product_set"][field])): + del request_init["product_set"][field][i][subfield] + else: + del request_init["product_set"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_product_set_rest_required_fields(request_type=product_search_service.UpdateProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "patch", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("productSet", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_update_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_update_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.UpdateProductSetRequest.pb(product_search_service.UpdateProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.UpdateProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.update_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.UpdateProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_product_set(request) + + +def test_update_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{product_set.name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_update_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductSetRequest, + dict, +]) +def test_delete_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_set_rest_required_fields(request_type=product_search_service.DeleteProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteProductSetRequest.pb(product_search_service.DeleteProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_product_set(request) + + +def test_delete_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_delete_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + + +def test_delete_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductRequest, + dict, +]) +def test_create_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request_init["product"] = {'name': 'name_value', 'display_name': 'display_name_value', 'description': 'description_value', 'product_category': 'product_category_value', 'product_labels': [{'key': 'key_value', 'value': 'value_value'}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateProductRequest.meta.fields["product"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product"][field])): + del request_init["product"][field][i][subfield] + else: + del request_init["product"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_create_product_rest_required_fields(request_type=product_search_service.CreateProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("product_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productId", )) & set(("parent", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateProductRequest.pb(product_search_service.CreateProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.CreateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.create_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_product(request) + + +def test_create_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*/locations/*}/products" % client.transport._host, args[1]) + + +def test_create_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + +def test_create_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsRequest, + dict, +]) +def test_list_products_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_products(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_rest_required_fields(request_type=product_search_service.ListProductsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_products(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_products_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_products") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductsRequest.pb(product_search_service.ListProductsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductsResponse.to_json(product_search_service.ListProductsResponse()) + + request = product_search_service.ListProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductsResponse() + + client.list_products(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_products_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_products(request) + + +def test_list_products_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_products(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*/locations/*}/products" % client.transport._host, args[1]) + + +def test_list_products_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + pager = client.list_products(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) + + pages = list(client.list_products(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductRequest, + dict, +]) +def test_get_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_get_product_rest_required_fields(request_type=product_search_service.GetProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetProductRequest.pb(product_search_service.GetProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.GetProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.get_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_product(request) + + +def test_get_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_get_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + + +def test_get_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductRequest, + dict, +]) +def test_update_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + request_init["product"] = {'name': 'projects/sample1/locations/sample2/products/sample3', 'display_name': 'display_name_value', 'description': 'description_value', 'product_category': 'product_category_value', 'product_labels': [{'key': 'key_value', 'value': 'value_value'}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.UpdateProductRequest.meta.fields["product"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product"][field])): + del request_init["product"][field][i][subfield] + else: + del request_init["product"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_update_product_rest_required_fields(request_type=product_search_service.UpdateProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "patch", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_update_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_update_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.UpdateProductRequest.pb(product_search_service.UpdateProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.UpdateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.update_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.UpdateProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_product(request) + + +def test_update_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{product.name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_update_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductRequest, + dict, +]) +def test_delete_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_product(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_rest_required_fields(request_type=product_search_service.DeleteProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_product") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteProductRequest.pb(product_search_service.DeleteProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_product(request) + + +def test_delete_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_delete_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + + +def test_delete_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateReferenceImageRequest, + dict, +]) +def test_create_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request_init["reference_image"] = {'name': 'name_value', 'uri': 'uri_value', 'bounding_polys': [{'vertices': [{'x': 120, 'y': 121}], 'normalized_vertices': [{'x': 0.12, 'y': 0.121}]}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateReferenceImageRequest.meta.fields["reference_image"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["reference_image"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["reference_image"][field])): + del request_init["reference_image"][field][i][subfield] + else: + del request_init["reference_image"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_reference_image(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_create_reference_image_rest_required_fields(request_type=product_search_service.CreateReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_reference_image._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("reference_image_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(("referenceImageId", )) & set(("parent", "referenceImage", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_reference_image") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_reference_image") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateReferenceImageRequest.pb(product_search_service.CreateReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ReferenceImage.to_json(product_search_service.ReferenceImage()) + + request = product_search_service.CreateReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ReferenceImage() + + client.create_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_reference_image(request) + + +def test_create_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*/locations/*/products/*}/referenceImages" % client.transport._host, args[1]) + + +def test_create_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + +def test_create_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteReferenceImageRequest, + dict, +]) +def test_delete_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_reference_image(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_reference_image_rest_required_fields(request_type=product_search_service.DeleteReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_reference_image") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteReferenceImageRequest.pb(product_search_service.DeleteReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_reference_image(request) + + +def test_delete_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/products/*/referenceImages/*}" % client.transport._host, args[1]) + + +def test_delete_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + + +def test_delete_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListReferenceImagesRequest, + dict, +]) +def test_list_reference_images_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_reference_images(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +def test_list_reference_images_rest_required_fields(request_type=product_search_service.ListReferenceImagesRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_reference_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_reference_images._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_reference_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_reference_images_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_reference_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_reference_images_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_reference_images") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_reference_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListReferenceImagesRequest.pb(product_search_service.ListReferenceImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListReferenceImagesResponse.to_json(product_search_service.ListReferenceImagesResponse()) + + request = product_search_service.ListReferenceImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListReferenceImagesResponse() + + client.list_reference_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_reference_images_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListReferenceImagesRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_reference_images(request) + + +def test_list_reference_images_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_reference_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*/locations/*/products/*}/referenceImages" % client.transport._host, args[1]) + + +def test_list_reference_images_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + + +def test_list_reference_images_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListReferenceImagesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + pager = client.list_reference_images(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in results) + + pages = list(client.list_reference_images(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetReferenceImageRequest, + dict, +]) +def test_get_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_reference_image(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_get_reference_image_rest_required_fields(request_type=product_search_service.GetReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_reference_image") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_reference_image") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetReferenceImageRequest.pb(product_search_service.GetReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ReferenceImage.to_json(product_search_service.ReferenceImage()) + + request = product_search_service.GetReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ReferenceImage() + + client.get_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_reference_image(request) + + +def test_get_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/products/*/referenceImages/*}" % client.transport._host, args[1]) + + +def test_get_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + + +def test_get_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.AddProductToProductSetRequest, + dict, +]) +def test_add_product_to_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_product_to_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_add_product_to_product_set_rest_required_fields(request_type=product_search_service.AddProductToProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request_init["product"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_product_to_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_product_to_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_product_to_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_product_to_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_product_to_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_product_to_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_add_product_to_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.AddProductToProductSetRequest.pb(product_search_service.AddProductToProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.AddProductToProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.add_product_to_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_add_product_to_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.AddProductToProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.add_product_to_product_set(request) + + +def test_add_product_to_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + product='product_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_product_to_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/productSets/*}:addProduct" % client.transport._host, args[1]) + + +def test_add_product_to_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + + +def test_add_product_to_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.RemoveProductFromProductSetRequest, + dict, +]) +def test_remove_product_from_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_product_from_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_remove_product_from_product_set_rest_required_fields(request_type=product_search_service.RemoveProductFromProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request_init["product"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_product_from_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_product_from_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_product_from_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_product_from_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_product_from_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_product_from_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_remove_product_from_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.RemoveProductFromProductSetRequest.pb(product_search_service.RemoveProductFromProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.RemoveProductFromProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.remove_product_from_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_remove_product_from_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.RemoveProductFromProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.remove_product_from_product_set(request) + + +def test_remove_product_from_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + product='product_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_product_from_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/productSets/*}:removeProduct" % client.transport._host, args[1]) + + +def test_remove_product_from_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + + +def test_remove_product_from_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsInProductSetRequest, + dict, +]) +def test_list_products_in_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_products_in_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_in_product_set_rest_required_fields(request_type=product_search_service.ListProductsInProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products_in_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products_in_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_products_in_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_products_in_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products_in_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_in_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_products_in_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_products_in_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductsInProductSetRequest.pb(product_search_service.ListProductsInProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductsInProductSetResponse.to_json(product_search_service.ListProductsInProductSetResponse()) + + request = product_search_service.ListProductsInProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductsInProductSetResponse() + + client.list_products_in_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_products_in_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductsInProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_products_in_product_set(request) + + +def test_list_products_in_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_products_in_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/locations/*/productSets/*}/products" % client.transport._host, args[1]) + + +def test_list_products_in_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + + +def test_list_products_in_product_set_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductsInProductSetResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + pager = client.list_products_in_product_set(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) + + pages = list(client.list_products_in_product_set(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ImportProductSetsRequest, + dict, +]) +def test_import_product_sets_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.import_product_sets(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_product_sets_rest_required_fields(request_type=product_search_service.ImportProductSetsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).import_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).import_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.import_product_sets(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_product_sets_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_product_sets._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_product_sets_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_import_product_sets") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_import_product_sets") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ImportProductSetsRequest.pb(product_search_service.ImportProductSetsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = product_search_service.ImportProductSetsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_product_sets(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_product_sets_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ImportProductSetsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.import_product_sets(request) + + +def test_import_product_sets_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.import_product_sets(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*/locations/*}/productSets:import" % client.transport._host, args[1]) + + +def test_import_product_sets_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + +def test_import_product_sets_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.PurgeProductsRequest, + dict, +]) +def test_purge_products_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.purge_products(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_purge_products_rest_required_fields(request_type=product_search_service.PurgeProductsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).purge_products._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).purge_products._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.purge_products(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_purge_products_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.purge_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_purge_products_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_purge_products") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_purge_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.PurgeProductsRequest.pb(product_search_service.PurgeProductsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = product_search_service.PurgeProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.purge_products(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_purge_products_rest_bad_request(transport: str = 'rest', request_type=product_search_service.PurgeProductsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.purge_products(request) + + +def test_purge_products_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.purge_products(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*/locations/*}/products:purge" % client.transport._host, args[1]) + + +def test_purge_products_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.purge_products( + product_search_service.PurgeProductsRequest(), + parent='parent_value', + ) + + +def test_purge_products_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProductSearchClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProductSearchGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + transports.ProductSearchRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "rest", +]) +def test_transport_kind(transport_name): + transport = ProductSearchClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ProductSearchGrpcTransport, + ) + +def test_product_search_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ProductSearchTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_product_search_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.vision_v1.services.product_search.transports.ProductSearchTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ProductSearchTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_product_set', + 'list_product_sets', + 'get_product_set', + 'update_product_set', + 'delete_product_set', + 'create_product', + 'list_products', + 'get_product', + 'update_product', + 'delete_product', + 'create_reference_image', + 'delete_reference_image', + 'list_reference_images', + 'get_reference_image', + 'add_product_to_product_set', + 'remove_product_from_product_set', + 'list_products_in_product_set', + 'import_product_sets', + 'purge_products', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_product_search_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.vision_v1.services.product_search.transports.ProductSearchTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductSearchTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id="octopus", + ) + + +def test_product_search_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.vision_v1.services.product_search.transports.ProductSearchTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductSearchTransport() + adc.assert_called_once() + + +def test_product_search_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ProductSearchClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + ], +) +def test_product_search_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-vision',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + transports.ProductSearchRestTransport, + ], +) +def test_product_search_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ProductSearchGrpcTransport, grpc_helpers), + (transports.ProductSearchGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_product_search_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=["1", "2"], + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_product_search_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel") as mock_configure_mtls_channel: + transports.ProductSearchRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_product_search_rest_lro_client(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_search_host_no_port(transport_name): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_search_host_with_port(transport_name): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_product_search_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ProductSearchClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ProductSearchClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_product_set._session + session2 = client2.transport.create_product_set._session + assert session1 != session2 + session1 = client1.transport.list_product_sets._session + session2 = client2.transport.list_product_sets._session + assert session1 != session2 + session1 = client1.transport.get_product_set._session + session2 = client2.transport.get_product_set._session + assert session1 != session2 + session1 = client1.transport.update_product_set._session + session2 = client2.transport.update_product_set._session + assert session1 != session2 + session1 = client1.transport.delete_product_set._session + session2 = client2.transport.delete_product_set._session + assert session1 != session2 + session1 = client1.transport.create_product._session + session2 = client2.transport.create_product._session + assert session1 != session2 + session1 = client1.transport.list_products._session + session2 = client2.transport.list_products._session + assert session1 != session2 + session1 = client1.transport.get_product._session + session2 = client2.transport.get_product._session + assert session1 != session2 + session1 = client1.transport.update_product._session + session2 = client2.transport.update_product._session + assert session1 != session2 + session1 = client1.transport.delete_product._session + session2 = client2.transport.delete_product._session + assert session1 != session2 + session1 = client1.transport.create_reference_image._session + session2 = client2.transport.create_reference_image._session + assert session1 != session2 + session1 = client1.transport.delete_reference_image._session + session2 = client2.transport.delete_reference_image._session + assert session1 != session2 + session1 = client1.transport.list_reference_images._session + session2 = client2.transport.list_reference_images._session + assert session1 != session2 + session1 = client1.transport.get_reference_image._session + session2 = client2.transport.get_reference_image._session + assert session1 != session2 + session1 = client1.transport.add_product_to_product_set._session + session2 = client2.transport.add_product_to_product_set._session + assert session1 != session2 + session1 = client1.transport.remove_product_from_product_set._session + session2 = client2.transport.remove_product_from_product_set._session + assert session1 != session2 + session1 = client1.transport.list_products_in_product_set._session + session2 = client2.transport.list_products_in_product_set._session + assert session1 != session2 + session1 = client1.transport.import_product_sets._session + session2 = client2.transport.import_product_sets._session + assert session1 != session2 + session1 = client1.transport.purge_products._session + session2 = client2.transport.purge_products._session + assert session1 != session2 +def test_product_search_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductSearchGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_product_search_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductSearchGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_product_search_grpc_lro_client(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_search_grpc_lro_async_client(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_path(): + project = "squid" + location = "clam" + product = "whelk" + expected = "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + actual = ProductSearchClient.product_path(project, location, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "octopus", + "location": "oyster", + "product": "nudibranch", + } + path = ProductSearchClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_product_path(path) + assert expected == actual + +def test_product_set_path(): + project = "cuttlefish" + location = "mussel" + product_set = "winkle" + expected = "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + actual = ProductSearchClient.product_set_path(project, location, product_set) + assert expected == actual + + +def test_parse_product_set_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "product_set": "abalone", + } + path = ProductSearchClient.product_set_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_product_set_path(path) + assert expected == actual + +def test_reference_image_path(): + project = "squid" + location = "clam" + product = "whelk" + reference_image = "octopus" + expected = "projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}".format(project=project, location=location, product=product, reference_image=reference_image, ) + actual = ProductSearchClient.reference_image_path(project, location, product, reference_image) + assert expected == actual + + +def test_parse_reference_image_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "product": "cuttlefish", + "reference_image": "mussel", + } + path = ProductSearchClient.reference_image_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_reference_image_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "winkle" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ProductSearchClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nautilus", + } + path = ProductSearchClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "scallop" + expected = "folders/{folder}".format(folder=folder, ) + actual = ProductSearchClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "abalone", + } + path = ProductSearchClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "squid" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ProductSearchClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "clam", + } + path = ProductSearchClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "whelk" + expected = "projects/{project}".format(project=project, ) + actual = ProductSearchClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "octopus", + } + path = ProductSearchClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "oyster" + location = "nudibranch" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ProductSearchClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + } + path = ProductSearchClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ProductSearchTransport, '_prep_wrapped_messages') as prep: + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ProductSearchTransport, '_prep_wrapped_messages') as prep: + transport_class = ProductSearchClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/owl-bot-staging/v1p1beta1/.coveragerc b/owl-bot-staging/v1p1beta1/.coveragerc new file mode 100644 index 00000000..cbf0b85a --- /dev/null +++ b/owl-bot-staging/v1p1beta1/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/vision/__init__.py + google/cloud/vision/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/owl-bot-staging/v1p1beta1/.flake8 b/owl-bot-staging/v1p1beta1/.flake8 new file mode 100644 index 00000000..29227d4c --- /dev/null +++ b/owl-bot-staging/v1p1beta1/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2020 Google LLC +# +# Licensed 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 +# +# https://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. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/owl-bot-staging/v1p1beta1/MANIFEST.in b/owl-bot-staging/v1p1beta1/MANIFEST.in new file mode 100644 index 00000000..7fd81c6f --- /dev/null +++ b/owl-bot-staging/v1p1beta1/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/vision *.py +recursive-include google/cloud/vision_v1p1beta1 *.py diff --git a/owl-bot-staging/v1p1beta1/README.rst b/owl-bot-staging/v1p1beta1/README.rst new file mode 100644 index 00000000..39f9ca72 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Vision API +================================================= + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. Enable the Google Cloud Vision API. +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a `virtualenv`_ using pip. `virtualenv`_ is a tool to +create isolated Python environments. The basic problem it addresses is one of +dependencies and versions, and indirectly permissions. + +With `virtualenv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ + + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + /bin/pip install /path/to/library + + +Windows +^^^^^^^ + +.. code-block:: console + + python3 -m venv + \Scripts\activate + \Scripts\pip.exe install \path\to\library diff --git a/owl-bot-staging/v1p1beta1/docs/_static/custom.css b/owl-bot-staging/v1p1beta1/docs/_static/custom.css new file mode 100644 index 00000000..06423be0 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/v1p1beta1/docs/conf.py b/owl-bot-staging/v1p1beta1/docs/conf.py new file mode 100644 index 00000000..c75f569a --- /dev/null +++ b/owl-bot-staging/v1p1beta1/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# +# google-cloud-vision documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import shlex + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +__version__ = "0.1.0" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.0.1" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_flags = ["members"] +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# Allow markdown includes (so releases.md can include CHANGLEOG.md) +# http://www.sphinx-doc.org/en/master/markdown.html +source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = u"google-cloud-vision" +copyright = u"2023, Google, LLC" +author = u"Google APIs" # TODO: autogenerate this bit + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for Python", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-cloud-vision-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', + # Latex figure (float) alignment + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + root_doc, + "google-cloud-vision.tex", + u"google-cloud-vision Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + root_doc, + "google-cloud-vision", + u"Google Cloud Vision Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + root_doc, + "google-cloud-vision", + u"google-cloud-vision Documentation", + author, + "google-cloud-vision", + "GAPIC library for Google Cloud Vision API", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("http://python.readthedocs.org/en/latest/", None), + "gax": ("https://gax-python.readthedocs.org/en/latest/", None), + "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), + "google-gax": ("https://gax-python.readthedocs.io/en/latest/", None), + "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None), + "grpc": ("https://grpc.io/grpc/python/", None), + "requests": ("http://requests.kennethreitz.org/en/stable/", None), + "proto": ("https://proto-plus-python.readthedocs.io/en/stable", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/owl-bot-staging/v1p1beta1/docs/index.rst b/owl-bot-staging/v1p1beta1/docs/index.rst new file mode 100644 index 00000000..049cf367 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + vision_v1p1beta1/services + vision_v1p1beta1/types diff --git a/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/image_annotator.rst b/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/image_annotator.rst new file mode 100644 index 00000000..4aa9e5a2 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/image_annotator.rst @@ -0,0 +1,6 @@ +ImageAnnotator +-------------------------------- + +.. automodule:: google.cloud.vision_v1p1beta1.services.image_annotator + :members: + :inherited-members: diff --git a/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/services.rst b/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/services.rst new file mode 100644 index 00000000..1b046a84 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/services.rst @@ -0,0 +1,6 @@ +Services for Google Cloud Vision v1p1beta1 API +============================================== +.. toctree:: + :maxdepth: 2 + + image_annotator diff --git a/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/types.rst b/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/types.rst new file mode 100644 index 00000000..ef19cc15 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/docs/vision_v1p1beta1/types.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Vision v1p1beta1 API +=========================================== + +.. automodule:: google.cloud.vision_v1p1beta1.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision/__init__.py b/owl-bot-staging/v1p1beta1/google/cloud/vision/__init__.py new file mode 100644 index 00000000..f99fb4a7 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision/__init__.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.vision_v1p1beta1.services.image_annotator.client import ImageAnnotatorClient +from google.cloud.vision_v1p1beta1.services.image_annotator.async_client import ImageAnnotatorAsyncClient + +from google.cloud.vision_v1p1beta1.types.geometry import BoundingPoly +from google.cloud.vision_v1p1beta1.types.geometry import Position +from google.cloud.vision_v1p1beta1.types.geometry import Vertex +from google.cloud.vision_v1p1beta1.types.image_annotator import AnnotateImageRequest +from google.cloud.vision_v1p1beta1.types.image_annotator import AnnotateImageResponse +from google.cloud.vision_v1p1beta1.types.image_annotator import BatchAnnotateImagesRequest +from google.cloud.vision_v1p1beta1.types.image_annotator import BatchAnnotateImagesResponse +from google.cloud.vision_v1p1beta1.types.image_annotator import ColorInfo +from google.cloud.vision_v1p1beta1.types.image_annotator import CropHint +from google.cloud.vision_v1p1beta1.types.image_annotator import CropHintsAnnotation +from google.cloud.vision_v1p1beta1.types.image_annotator import CropHintsParams +from google.cloud.vision_v1p1beta1.types.image_annotator import DominantColorsAnnotation +from google.cloud.vision_v1p1beta1.types.image_annotator import EntityAnnotation +from google.cloud.vision_v1p1beta1.types.image_annotator import FaceAnnotation +from google.cloud.vision_v1p1beta1.types.image_annotator import Feature +from google.cloud.vision_v1p1beta1.types.image_annotator import Image +from google.cloud.vision_v1p1beta1.types.image_annotator import ImageContext +from google.cloud.vision_v1p1beta1.types.image_annotator import ImageProperties +from google.cloud.vision_v1p1beta1.types.image_annotator import ImageSource +from google.cloud.vision_v1p1beta1.types.image_annotator import LatLongRect +from google.cloud.vision_v1p1beta1.types.image_annotator import LocationInfo +from google.cloud.vision_v1p1beta1.types.image_annotator import Property +from google.cloud.vision_v1p1beta1.types.image_annotator import SafeSearchAnnotation +from google.cloud.vision_v1p1beta1.types.image_annotator import TextDetectionParams +from google.cloud.vision_v1p1beta1.types.image_annotator import WebDetectionParams +from google.cloud.vision_v1p1beta1.types.image_annotator import Likelihood +from google.cloud.vision_v1p1beta1.types.text_annotation import Block +from google.cloud.vision_v1p1beta1.types.text_annotation import Page +from google.cloud.vision_v1p1beta1.types.text_annotation import Paragraph +from google.cloud.vision_v1p1beta1.types.text_annotation import Symbol +from google.cloud.vision_v1p1beta1.types.text_annotation import TextAnnotation +from google.cloud.vision_v1p1beta1.types.text_annotation import Word +from google.cloud.vision_v1p1beta1.types.web_detection import WebDetection + +__all__ = ('ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', + 'BoundingPoly', + 'Position', + 'Vertex', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'Image', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'LatLongRect', + 'LocationInfo', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision/gapic_version.py b/owl-bot-staging/v1p1beta1/google/cloud/vision/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision/py.typed b/owl-bot-staging/v1p1beta1/google/cloud/vision/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/__init__.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/__init__.py new file mode 100644 index 00000000..632f4fd1 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/__init__.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision_v1p1beta1 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.image_annotator import ImageAnnotatorClient +from .services.image_annotator import ImageAnnotatorAsyncClient + +from .types.geometry import BoundingPoly +from .types.geometry import Position +from .types.geometry import Vertex +from .types.image_annotator import AnnotateImageRequest +from .types.image_annotator import AnnotateImageResponse +from .types.image_annotator import BatchAnnotateImagesRequest +from .types.image_annotator import BatchAnnotateImagesResponse +from .types.image_annotator import ColorInfo +from .types.image_annotator import CropHint +from .types.image_annotator import CropHintsAnnotation +from .types.image_annotator import CropHintsParams +from .types.image_annotator import DominantColorsAnnotation +from .types.image_annotator import EntityAnnotation +from .types.image_annotator import FaceAnnotation +from .types.image_annotator import Feature +from .types.image_annotator import Image +from .types.image_annotator import ImageContext +from .types.image_annotator import ImageProperties +from .types.image_annotator import ImageSource +from .types.image_annotator import LatLongRect +from .types.image_annotator import LocationInfo +from .types.image_annotator import Property +from .types.image_annotator import SafeSearchAnnotation +from .types.image_annotator import TextDetectionParams +from .types.image_annotator import WebDetectionParams +from .types.image_annotator import Likelihood +from .types.text_annotation import Block +from .types.text_annotation import Page +from .types.text_annotation import Paragraph +from .types.text_annotation import Symbol +from .types.text_annotation import TextAnnotation +from .types.text_annotation import Word +from .types.web_detection import WebDetection + +__all__ = ( + 'ImageAnnotatorAsyncClient', +'AnnotateImageRequest', +'AnnotateImageResponse', +'BatchAnnotateImagesRequest', +'BatchAnnotateImagesResponse', +'Block', +'BoundingPoly', +'ColorInfo', +'CropHint', +'CropHintsAnnotation', +'CropHintsParams', +'DominantColorsAnnotation', +'EntityAnnotation', +'FaceAnnotation', +'Feature', +'Image', +'ImageAnnotatorClient', +'ImageContext', +'ImageProperties', +'ImageSource', +'LatLongRect', +'Likelihood', +'LocationInfo', +'Page', +'Paragraph', +'Position', +'Property', +'SafeSearchAnnotation', +'Symbol', +'TextAnnotation', +'TextDetectionParams', +'Vertex', +'WebDetection', +'WebDetectionParams', +'Word', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/gapic_metadata.json b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/gapic_metadata.json new file mode 100644 index 00000000..b60375c4 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/gapic_metadata.json @@ -0,0 +1,43 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.vision_v1p1beta1", + "protoPackage": "google.cloud.vision.v1p1beta1", + "schema": "1.0", + "services": { + "ImageAnnotator": { + "clients": { + "grpc": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ImageAnnotatorAsyncClient", + "rpcs": { + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "rest": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/gapic_version.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/py.typed b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/__init__.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/__init__.py new file mode 100644 index 00000000..89a37dc9 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/__init__.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/__init__.py new file mode 100644 index 00000000..ee708f26 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .client import ImageAnnotatorClient +from .async_client import ImageAnnotatorAsyncClient + +__all__ = ( + 'ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/async_client.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/async_client.py new file mode 100644 index 00000000..f3ca3314 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/async_client.py @@ -0,0 +1,299 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.vision_v1p1beta1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.cloud.vision_v1p1beta1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .client import ImageAnnotatorClient + + +class ImageAnnotatorAsyncClient: + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + _client: ImageAnnotatorClient + + DEFAULT_ENDPOINT = ImageAnnotatorClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ImageAnnotatorClient.DEFAULT_MTLS_ENDPOINT + + common_billing_account_path = staticmethod(ImageAnnotatorClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ImageAnnotatorClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ImageAnnotatorClient.common_folder_path) + parse_common_folder_path = staticmethod(ImageAnnotatorClient.parse_common_folder_path) + common_organization_path = staticmethod(ImageAnnotatorClient.common_organization_path) + parse_common_organization_path = staticmethod(ImageAnnotatorClient.parse_common_organization_path) + common_project_path = staticmethod(ImageAnnotatorClient.common_project_path) + parse_common_project_path = staticmethod(ImageAnnotatorClient.parse_common_project_path) + common_location_path = staticmethod(ImageAnnotatorClient.common_location_path) + parse_common_location_path = staticmethod(ImageAnnotatorClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_info.__func__(ImageAnnotatorAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_file.__func__(ImageAnnotatorAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ImageAnnotatorClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ImageAnnotatorClient).get_transport_class, type(ImageAnnotatorClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ImageAnnotatorTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ImageAnnotatorClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p1beta1 + + async def sample_batch_annotate_images(): + # Create a client + client = vision_v1p1beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p1beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p1beta1.types.BatchAnnotateImagesRequest, dict]]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (:class:`MutableSequence[google.cloud.vision_v1p1beta1.types.AnnotateImageRequest]`): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p1beta1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.BatchAnnotateImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ImageAnnotatorAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorAsyncClient", +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/client.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/client.py new file mode 100644 index 00000000..64c73974 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/client.py @@ -0,0 +1,487 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import os +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast + +from google.cloud.vision_v1p1beta1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.cloud.vision_v1p1beta1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ImageAnnotatorGrpcTransport +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .transports.rest import ImageAnnotatorRestTransport + + +class ImageAnnotatorClientMeta(type): + """Metaclass for the ImageAnnotator client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] + _transport_registry["grpc"] = ImageAnnotatorGrpcTransport + _transport_registry["grpc_asyncio"] = ImageAnnotatorGrpcAsyncIOTransport + _transport_registry["rest"] = ImageAnnotatorRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ImageAnnotatorTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ImageAnnotatorClient(metaclass=ImageAnnotatorClientMeta): + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "vision.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ImageAnnotatorTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ImageAnnotatorTransport): + # transport is a ImageAnnotatorTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p1beta1 + + def sample_batch_annotate_images(): + # Create a client + client = vision_v1p1beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p1beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p1beta1.types.BatchAnnotateImagesRequest, dict]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (MutableSequence[google.cloud.vision_v1p1beta1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p1beta1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.BatchAnnotateImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.BatchAnnotateImagesRequest): + request = image_annotator.BatchAnnotateImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_annotate_images] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ImageAnnotatorClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorClient", +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/__init__.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/__init__.py new file mode 100644 index 00000000..ad6cf948 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +from typing import Dict, Type + +from .base import ImageAnnotatorTransport +from .grpc import ImageAnnotatorGrpcTransport +from .grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .rest import ImageAnnotatorRestTransport +from .rest import ImageAnnotatorRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] +_transport_registry['grpc'] = ImageAnnotatorGrpcTransport +_transport_registry['grpc_asyncio'] = ImageAnnotatorGrpcAsyncIOTransport +_transport_registry['rest'] = ImageAnnotatorRestTransport + +__all__ = ( + 'ImageAnnotatorTransport', + 'ImageAnnotatorGrpcTransport', + 'ImageAnnotatorGrpcAsyncIOTransport', + 'ImageAnnotatorRestTransport', + 'ImageAnnotatorRestInterceptor', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/base.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/base.py new file mode 100644 index 00000000..4cfe0f6d --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/base.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.vision_v1p1beta1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.vision_v1p1beta1.types import image_annotator + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ImageAnnotatorTransport(abc.ABC): + """Abstract transport class for ImageAnnotator.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', + ) + + DEFAULT_HOST: str = 'vision.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience(api_audience if api_audience else host) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.batch_annotate_images: gapic_v1.method.wrap_method( + self.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Union[ + image_annotator.BatchAnnotateImagesResponse, + Awaitable[image_annotator.BatchAnnotateImagesResponse] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ImageAnnotatorTransport', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/grpc.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/grpc.py new file mode 100644 index 00000000..4a5d8f08 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/grpc.py @@ -0,0 +1,268 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.vision_v1p1beta1.types import image_annotator +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO + + +class ImageAnnotatorGrpcTransport(ImageAnnotatorTransport): + """gRPC backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + ~.BatchAnnotateImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p1beta1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ImageAnnotatorGrpcTransport', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/grpc_asyncio.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/grpc_asyncio.py new file mode 100644 index 00000000..1feee406 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/grpc_asyncio.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.vision_v1p1beta1.types import image_annotator +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .grpc import ImageAnnotatorGrpcTransport + + +class ImageAnnotatorGrpcAsyncIOTransport(ImageAnnotatorTransport): + """gRPC AsyncIO backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Awaitable[image_annotator.BatchAnnotateImagesResponse]]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + Awaitable[~.BatchAnnotateImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p1beta1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ImageAnnotatorGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/rest.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/rest.py new file mode 100644 index 00000000..55cf3377 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/services/image_annotator/transports/rest.py @@ -0,0 +1,303 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.auth.transport.requests import AuthorizedSession # type: ignore +import json # type: ignore +import grpc # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.api_core import rest_helpers +from google.api_core import rest_streaming +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from requests import __version__ as requests_version +import dataclasses +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.cloud.vision_v1p1beta1.types import image_annotator + +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ImageAnnotatorRestInterceptor: + """Interceptor for ImageAnnotator. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ImageAnnotatorRestTransport. + + .. code-block:: python + class MyCustomImageAnnotatorInterceptor(ImageAnnotatorRestInterceptor): + def pre_batch_annotate_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_annotate_images(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ImageAnnotatorRestTransport(interceptor=MyCustomImageAnnotatorInterceptor()) + client = ImageAnnotatorClient(transport=transport) + + + """ + def pre_batch_annotate_images(self, request: image_annotator.BatchAnnotateImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.BatchAnnotateImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_batch_annotate_images(self, response: image_annotator.BatchAnnotateImagesResponse) -> image_annotator.BatchAnnotateImagesResponse: + """Post-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ImageAnnotatorRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ImageAnnotatorRestInterceptor + + +class ImageAnnotatorRestTransport(ImageAnnotatorTransport): + """REST backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[ + ], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + interceptor: Optional[ImageAnnotatorRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError(f"Unexpected hostname structure: {host}") # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ImageAnnotatorRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _BatchAnnotateImages(ImageAnnotatorRestStub): + def __hash__(self): + return hash("BatchAnnotateImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.BatchAnnotateImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Call the batch annotate images method over HTTP. + + Args: + request (~.image_annotator.BatchAnnotateImagesRequest): + The request object. Multiple image annotation requests + are batched into a single service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.image_annotator.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p1beta1/images:annotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_annotate_images(request, metadata) + pb_request = image_annotator.BatchAnnotateImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = image_annotator.BatchAnnotateImagesResponse() + pb_resp = image_annotator.BatchAnnotateImagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_annotate_images(resp) + return resp + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchAnnotateImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ImageAnnotatorRestTransport', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/__init__.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/__init__.py new file mode 100644 index 00000000..62f6cce2 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/__init__.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .geometry import ( + BoundingPoly, + Position, + Vertex, +) +from .image_annotator import ( + AnnotateImageRequest, + AnnotateImageResponse, + BatchAnnotateImagesRequest, + BatchAnnotateImagesResponse, + ColorInfo, + CropHint, + CropHintsAnnotation, + CropHintsParams, + DominantColorsAnnotation, + EntityAnnotation, + FaceAnnotation, + Feature, + Image, + ImageContext, + ImageProperties, + ImageSource, + LatLongRect, + LocationInfo, + Property, + SafeSearchAnnotation, + TextDetectionParams, + WebDetectionParams, + Likelihood, +) +from .text_annotation import ( + Block, + Page, + Paragraph, + Symbol, + TextAnnotation, + Word, +) +from .web_detection import ( + WebDetection, +) + +__all__ = ( + 'BoundingPoly', + 'Position', + 'Vertex', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'Image', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'LatLongRect', + 'LocationInfo', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/geometry.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/geometry.py new file mode 100644 index 00000000..6d66a717 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/geometry.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p1beta1', + manifest={ + 'Vertex', + 'BoundingPoly', + 'Position', + }, +) + + +class Vertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the vertex coordinates are in the same scale as the + original image. + + Attributes: + x (int): + X coordinate. + y (int): + Y coordinate. + """ + + x: int = proto.Field( + proto.INT32, + number=1, + ) + y: int = proto.Field( + proto.INT32, + number=2, + ) + + +class BoundingPoly(proto.Message): + r"""A bounding polygon for the detected image annotation. + + Attributes: + vertices (MutableSequence[google.cloud.vision_v1p1beta1.types.Vertex]): + The bounding polygon vertices. + """ + + vertices: MutableSequence['Vertex'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Vertex', + ) + + +class Position(proto.Message): + r"""A 3D position in the image, used primarily for Face detection + landmarks. A valid Position must have both x and y coordinates. + The position coordinates are in the same scale as the original + image. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + z (float): + Z coordinate (or depth). + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + z: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/image_annotator.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/image_annotator.py new file mode 100644 index 00000000..f51fbabc --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/image_annotator.py @@ -0,0 +1,1080 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p1beta1.types import geometry +from google.cloud.vision_v1p1beta1.types import text_annotation +from google.cloud.vision_v1p1beta1.types import web_detection as gcv_web_detection +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import latlng_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p1beta1', + manifest={ + 'Likelihood', + 'Feature', + 'ImageSource', + 'Image', + 'FaceAnnotation', + 'LocationInfo', + 'Property', + 'EntityAnnotation', + 'SafeSearchAnnotation', + 'LatLongRect', + 'ColorInfo', + 'DominantColorsAnnotation', + 'ImageProperties', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'WebDetectionParams', + 'TextDetectionParams', + 'ImageContext', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + }, +) + + +class Likelihood(proto.Enum): + r"""A bucketized representation of likelihood, which is intended + to give clients highly stable results across model upgrades. + + Values: + UNKNOWN (0): + Unknown likelihood. + VERY_UNLIKELY (1): + It is very unlikely that the image belongs to + the specified vertical. + UNLIKELY (2): + It is unlikely that the image belongs to the + specified vertical. + POSSIBLE (3): + It is possible that the image belongs to the + specified vertical. + LIKELY (4): + It is likely that the image belongs to the + specified vertical. + VERY_LIKELY (5): + It is very likely that the image belongs to + the specified vertical. + """ + UNKNOWN = 0 + VERY_UNLIKELY = 1 + UNLIKELY = 2 + POSSIBLE = 3 + LIKELY = 4 + VERY_LIKELY = 5 + + +class Feature(proto.Message): + r"""Users describe the type of Google Cloud Vision API tasks to perform + over images by using *Feature*\ s. Each Feature indicates a type of + image detection task to perform. Features encode the Cloud Vision + API vertical to operate on and the number of top-scoring results to + return. + + Attributes: + type_ (google.cloud.vision_v1p1beta1.types.Feature.Type): + The feature type. + max_results (int): + Maximum number of results of this type. + model (str): + Model to use for the feature. Supported values: + "builtin/stable" (the default if unset) and + "builtin/latest". ``DOCUMENT_TEXT_DETECTION`` and + ``TEXT_DETECTION`` also support "builtin/weekly" for the + bleeding edge release updated weekly. + """ + class Type(proto.Enum): + r"""Type of image feature. + + Values: + TYPE_UNSPECIFIED (0): + Unspecified feature type. + FACE_DETECTION (1): + Run face detection. + LANDMARK_DETECTION (2): + Run landmark detection. + LOGO_DETECTION (3): + Run logo detection. + LABEL_DETECTION (4): + Run label detection. + TEXT_DETECTION (5): + Run OCR. + DOCUMENT_TEXT_DETECTION (11): + Run dense text document OCR. Takes precedence when both + DOCUMENT_TEXT_DETECTION and TEXT_DETECTION are present. + SAFE_SEARCH_DETECTION (6): + Run computer vision models to compute image + safe-search properties. + IMAGE_PROPERTIES (7): + Compute a set of image properties, such as + the image's dominant colors. + CROP_HINTS (9): + Run crop hints. + WEB_DETECTION (10): + Run web detection. + """ + TYPE_UNSPECIFIED = 0 + FACE_DETECTION = 1 + LANDMARK_DETECTION = 2 + LOGO_DETECTION = 3 + LABEL_DETECTION = 4 + TEXT_DETECTION = 5 + DOCUMENT_TEXT_DETECTION = 11 + SAFE_SEARCH_DETECTION = 6 + IMAGE_PROPERTIES = 7 + CROP_HINTS = 9 + WEB_DETECTION = 10 + + type_: Type = proto.Field( + proto.ENUM, + number=1, + enum=Type, + ) + max_results: int = proto.Field( + proto.INT32, + number=2, + ) + model: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ImageSource(proto.Message): + r"""External image source (Google Cloud Storage image location). + + Attributes: + gcs_image_uri (str): + NOTE: For new code ``image_uri`` below is preferred. Google + Cloud Storage image URI, which must be in the following + form: ``gs://bucket_name/object_name`` (for details, see + `Google Cloud Storage Request + URIs `__). + NOTE: Cloud Storage object versioning is not supported. + image_uri (str): + Image URI which supports: + + 1) Google Cloud Storage image URI, which must be in the + following form: ``gs://bucket_name/object_name`` (for + details, see `Google Cloud Storage Request + URIs `__). + NOTE: Cloud Storage object versioning is not supported. + 2) Publicly accessible image HTTP/HTTPS URL. This is + preferred over the legacy ``gcs_image_uri`` above. When + both ``gcs_image_uri`` and ``image_uri`` are specified, + ``image_uri`` takes precedence. + """ + + gcs_image_uri: str = proto.Field( + proto.STRING, + number=1, + ) + image_uri: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Image(proto.Message): + r"""Client image to perform Google Cloud Vision API tasks over. + + Attributes: + content (bytes): + Image content, represented as a stream of bytes. Note: as + with all ``bytes`` fields, protobuffers use a pure binary + representation, whereas JSON representations use base64. + source (google.cloud.vision_v1p1beta1.types.ImageSource): + Google Cloud Storage image location. If both ``content`` and + ``source`` are provided for an image, ``content`` takes + precedence and is used to perform the image annotation + request. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + source: 'ImageSource' = proto.Field( + proto.MESSAGE, + number=2, + message='ImageSource', + ) + + +class FaceAnnotation(proto.Message): + r"""A face annotation object contains the results of face + detection. + + Attributes: + bounding_poly (google.cloud.vision_v1p1beta1.types.BoundingPoly): + The bounding polygon around the face. The coordinates of the + bounding box are in the original image's scale, as returned + in ``ImageParams``. The bounding box is computed to "frame" + the face in accordance with human expectations. It is based + on the landmarker results. Note that one or more x and/or y + coordinates may not be generated in the ``BoundingPoly`` + (the polygon will be unbounded) if only a partial face + appears in the image to be annotated. + fd_bounding_poly (google.cloud.vision_v1p1beta1.types.BoundingPoly): + The ``fd_bounding_poly`` bounding polygon is tighter than + the ``boundingPoly``, and encloses only the skin part of the + face. Typically, it is used to eliminate the face from any + image analysis that detects the "amount of skin" visible in + an image. It is not based on the landmarker results, only on + the initial face detection, hence the fd (face detection) + prefix. + landmarks (MutableSequence[google.cloud.vision_v1p1beta1.types.FaceAnnotation.Landmark]): + Detected face landmarks. + roll_angle (float): + Roll angle, which indicates the amount of + clockwise/anti-clockwise rotation of the face relative to + the image vertical about the axis perpendicular to the face. + Range [-180,180]. + pan_angle (float): + Yaw angle, which indicates the leftward/rightward angle that + the face is pointing relative to the vertical plane + perpendicular to the image. Range [-180,180]. + tilt_angle (float): + Pitch angle, which indicates the upwards/downwards angle + that the face is pointing relative to the image's horizontal + plane. Range [-180,180]. + detection_confidence (float): + Detection confidence. Range [0, 1]. + landmarking_confidence (float): + Face landmarking confidence. Range [0, 1]. + joy_likelihood (google.cloud.vision_v1p1beta1.types.Likelihood): + Joy likelihood. + sorrow_likelihood (google.cloud.vision_v1p1beta1.types.Likelihood): + Sorrow likelihood. + anger_likelihood (google.cloud.vision_v1p1beta1.types.Likelihood): + Anger likelihood. + surprise_likelihood (google.cloud.vision_v1p1beta1.types.Likelihood): + Surprise likelihood. + under_exposed_likelihood (google.cloud.vision_v1p1beta1.types.Likelihood): + Under-exposed likelihood. + blurred_likelihood (google.cloud.vision_v1p1beta1.types.Likelihood): + Blurred likelihood. + headwear_likelihood (google.cloud.vision_v1p1beta1.types.Likelihood): + Headwear likelihood. + """ + + class Landmark(proto.Message): + r"""A face-specific landmark (for example, a face feature). + + Attributes: + type_ (google.cloud.vision_v1p1beta1.types.FaceAnnotation.Landmark.Type): + Face landmark type. + position (google.cloud.vision_v1p1beta1.types.Position): + Face landmark position. + """ + class Type(proto.Enum): + r"""Face landmark (feature) type. Left and right are defined from the + vantage of the viewer of the image without considering mirror + projections typical of photos. So, ``LEFT_EYE``, typically, is the + person's right eye. + + Values: + UNKNOWN_LANDMARK (0): + Unknown face landmark detected. Should not be + filled. + LEFT_EYE (1): + Left eye. + RIGHT_EYE (2): + Right eye. + LEFT_OF_LEFT_EYEBROW (3): + Left of left eyebrow. + RIGHT_OF_LEFT_EYEBROW (4): + Right of left eyebrow. + LEFT_OF_RIGHT_EYEBROW (5): + Left of right eyebrow. + RIGHT_OF_RIGHT_EYEBROW (6): + Right of right eyebrow. + MIDPOINT_BETWEEN_EYES (7): + Midpoint between eyes. + NOSE_TIP (8): + Nose tip. + UPPER_LIP (9): + Upper lip. + LOWER_LIP (10): + Lower lip. + MOUTH_LEFT (11): + Mouth left. + MOUTH_RIGHT (12): + Mouth right. + MOUTH_CENTER (13): + Mouth center. + NOSE_BOTTOM_RIGHT (14): + Nose, bottom right. + NOSE_BOTTOM_LEFT (15): + Nose, bottom left. + NOSE_BOTTOM_CENTER (16): + Nose, bottom center. + LEFT_EYE_TOP_BOUNDARY (17): + Left eye, top boundary. + LEFT_EYE_RIGHT_CORNER (18): + Left eye, right corner. + LEFT_EYE_BOTTOM_BOUNDARY (19): + Left eye, bottom boundary. + LEFT_EYE_LEFT_CORNER (20): + Left eye, left corner. + RIGHT_EYE_TOP_BOUNDARY (21): + Right eye, top boundary. + RIGHT_EYE_RIGHT_CORNER (22): + Right eye, right corner. + RIGHT_EYE_BOTTOM_BOUNDARY (23): + Right eye, bottom boundary. + RIGHT_EYE_LEFT_CORNER (24): + Right eye, left corner. + LEFT_EYEBROW_UPPER_MIDPOINT (25): + Left eyebrow, upper midpoint. + RIGHT_EYEBROW_UPPER_MIDPOINT (26): + Right eyebrow, upper midpoint. + LEFT_EAR_TRAGION (27): + Left ear tragion. + RIGHT_EAR_TRAGION (28): + Right ear tragion. + LEFT_EYE_PUPIL (29): + Left eye pupil. + RIGHT_EYE_PUPIL (30): + Right eye pupil. + FOREHEAD_GLABELLA (31): + Forehead glabella. + CHIN_GNATHION (32): + Chin gnathion. + CHIN_LEFT_GONION (33): + Chin left gonion. + CHIN_RIGHT_GONION (34): + Chin right gonion. + """ + UNKNOWN_LANDMARK = 0 + LEFT_EYE = 1 + RIGHT_EYE = 2 + LEFT_OF_LEFT_EYEBROW = 3 + RIGHT_OF_LEFT_EYEBROW = 4 + LEFT_OF_RIGHT_EYEBROW = 5 + RIGHT_OF_RIGHT_EYEBROW = 6 + MIDPOINT_BETWEEN_EYES = 7 + NOSE_TIP = 8 + UPPER_LIP = 9 + LOWER_LIP = 10 + MOUTH_LEFT = 11 + MOUTH_RIGHT = 12 + MOUTH_CENTER = 13 + NOSE_BOTTOM_RIGHT = 14 + NOSE_BOTTOM_LEFT = 15 + NOSE_BOTTOM_CENTER = 16 + LEFT_EYE_TOP_BOUNDARY = 17 + LEFT_EYE_RIGHT_CORNER = 18 + LEFT_EYE_BOTTOM_BOUNDARY = 19 + LEFT_EYE_LEFT_CORNER = 20 + RIGHT_EYE_TOP_BOUNDARY = 21 + RIGHT_EYE_RIGHT_CORNER = 22 + RIGHT_EYE_BOTTOM_BOUNDARY = 23 + RIGHT_EYE_LEFT_CORNER = 24 + LEFT_EYEBROW_UPPER_MIDPOINT = 25 + RIGHT_EYEBROW_UPPER_MIDPOINT = 26 + LEFT_EAR_TRAGION = 27 + RIGHT_EAR_TRAGION = 28 + LEFT_EYE_PUPIL = 29 + RIGHT_EYE_PUPIL = 30 + FOREHEAD_GLABELLA = 31 + CHIN_GNATHION = 32 + CHIN_LEFT_GONION = 33 + CHIN_RIGHT_GONION = 34 + + type_: 'FaceAnnotation.Landmark.Type' = proto.Field( + proto.ENUM, + number=3, + enum='FaceAnnotation.Landmark.Type', + ) + position: geometry.Position = proto.Field( + proto.MESSAGE, + number=4, + message=geometry.Position, + ) + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + fd_bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + landmarks: MutableSequence[Landmark] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=Landmark, + ) + roll_angle: float = proto.Field( + proto.FLOAT, + number=4, + ) + pan_angle: float = proto.Field( + proto.FLOAT, + number=5, + ) + tilt_angle: float = proto.Field( + proto.FLOAT, + number=6, + ) + detection_confidence: float = proto.Field( + proto.FLOAT, + number=7, + ) + landmarking_confidence: float = proto.Field( + proto.FLOAT, + number=8, + ) + joy_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + sorrow_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=10, + enum='Likelihood', + ) + anger_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=11, + enum='Likelihood', + ) + surprise_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=12, + enum='Likelihood', + ) + under_exposed_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=13, + enum='Likelihood', + ) + blurred_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=14, + enum='Likelihood', + ) + headwear_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=15, + enum='Likelihood', + ) + + +class LocationInfo(proto.Message): + r"""Detected entity location information. + + Attributes: + lat_lng (google.type.latlng_pb2.LatLng): + lat/long location coordinates. + """ + + lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + + +class Property(proto.Message): + r"""A ``Property`` consists of a user-supplied name/value pair. + + Attributes: + name (str): + Name of the property. + value (str): + Value of the property. + uint64_value (int): + Value of numeric properties. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + uint64_value: int = proto.Field( + proto.UINT64, + number=3, + ) + + +class EntityAnnotation(proto.Message): + r"""Set of detected entity features. + + Attributes: + mid (str): + Opaque entity ID. Some IDs may be available in `Google + Knowledge Graph Search + API `__. + locale (str): + The language code for the locale in which the entity textual + ``description`` is expressed. + description (str): + Entity textual description, expressed in its ``locale`` + language. + score (float): + Overall score of the result. Range [0, 1]. + confidence (float): + The accuracy of the entity detection in an image. For + example, for an image in which the "Eiffel Tower" entity is + detected, this field represents the confidence that there is + a tower in the query image. Range [0, 1]. + topicality (float): + The relevancy of the ICA (Image Content Annotation) label to + the image. For example, the relevancy of "tower" is likely + higher to an image containing the detected "Eiffel Tower" + than to an image containing a detected distant towering + building, even though the confidence that there is a tower + in each image may be the same. Range [0, 1]. + bounding_poly (google.cloud.vision_v1p1beta1.types.BoundingPoly): + Image region to which this entity belongs. Not produced for + ``LABEL_DETECTION`` features. + locations (MutableSequence[google.cloud.vision_v1p1beta1.types.LocationInfo]): + The location information for the detected entity. Multiple + ``LocationInfo`` elements can be present because one + location may indicate the location of the scene in the + image, and another location may indicate the location of the + place where the image was taken. Location information is + usually present for landmarks. + properties (MutableSequence[google.cloud.vision_v1p1beta1.types.Property]): + Some entities may have optional user-supplied ``Property`` + (name/value) fields, such a score or string that qualifies + the entity. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + locale: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + topicality: float = proto.Field( + proto.FLOAT, + number=6, + ) + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=7, + message=geometry.BoundingPoly, + ) + locations: MutableSequence['LocationInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message='LocationInfo', + ) + properties: MutableSequence['Property'] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message='Property', + ) + + +class SafeSearchAnnotation(proto.Message): + r"""Set of features pertaining to the image, computed by computer + vision methods over safe-search verticals (for example, adult, + spoof, medical, violence). + + Attributes: + adult (google.cloud.vision_v1p1beta1.types.Likelihood): + Represents the adult content likelihood for + the image. Adult content may contain elements + such as nudity, pornographic images or cartoons, + or sexual activities. + spoof (google.cloud.vision_v1p1beta1.types.Likelihood): + Spoof likelihood. The likelihood that an + modification was made to the image's canonical + version to make it appear funny or offensive. + medical (google.cloud.vision_v1p1beta1.types.Likelihood): + Likelihood that this is a medical image. + violence (google.cloud.vision_v1p1beta1.types.Likelihood): + Likelihood that this image contains violent + content. + racy (google.cloud.vision_v1p1beta1.types.Likelihood): + Likelihood that the request image contains + racy content. Racy content may include (but is + not limited to) skimpy or sheer clothing, + strategically covered nudity, lewd or + provocative poses, or close-ups of sensitive + body areas. + """ + + adult: 'Likelihood' = proto.Field( + proto.ENUM, + number=1, + enum='Likelihood', + ) + spoof: 'Likelihood' = proto.Field( + proto.ENUM, + number=2, + enum='Likelihood', + ) + medical: 'Likelihood' = proto.Field( + proto.ENUM, + number=3, + enum='Likelihood', + ) + violence: 'Likelihood' = proto.Field( + proto.ENUM, + number=4, + enum='Likelihood', + ) + racy: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + + +class LatLongRect(proto.Message): + r"""Rectangle determined by min and max ``LatLng`` pairs. + + Attributes: + min_lat_lng (google.type.latlng_pb2.LatLng): + Min lat/long pair. + max_lat_lng (google.type.latlng_pb2.LatLng): + Max lat/long pair. + """ + + min_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + max_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=2, + message=latlng_pb2.LatLng, + ) + + +class ColorInfo(proto.Message): + r"""Color information consists of RGB channels, score, and the + fraction of the image that the color occupies in the image. + + Attributes: + color (google.type.color_pb2.Color): + RGB components of the color. + score (float): + Image-specific score for this color. Value in range [0, 1]. + pixel_fraction (float): + The fraction of pixels the color occupies in the image. + Value in range [0, 1]. + """ + + color: color_pb2.Color = proto.Field( + proto.MESSAGE, + number=1, + message=color_pb2.Color, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + pixel_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class DominantColorsAnnotation(proto.Message): + r"""Set of dominant colors and their corresponding scores. + + Attributes: + colors (MutableSequence[google.cloud.vision_v1p1beta1.types.ColorInfo]): + RGB color values with their score and pixel + fraction. + """ + + colors: MutableSequence['ColorInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ColorInfo', + ) + + +class ImageProperties(proto.Message): + r"""Stores image properties, such as dominant colors. + + Attributes: + dominant_colors (google.cloud.vision_v1p1beta1.types.DominantColorsAnnotation): + If present, dominant colors completed + successfully. + """ + + dominant_colors: 'DominantColorsAnnotation' = proto.Field( + proto.MESSAGE, + number=1, + message='DominantColorsAnnotation', + ) + + +class CropHint(proto.Message): + r"""Single crop hint that is used to generate a new crop when + serving an image. + + Attributes: + bounding_poly (google.cloud.vision_v1p1beta1.types.BoundingPoly): + The bounding polygon for the crop region. The coordinates of + the bounding box are in the original image's scale, as + returned in ``ImageParams``. + confidence (float): + Confidence of this being a salient region. Range [0, 1]. + importance_fraction (float): + Fraction of importance of this salient region + with respect to the original image. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + importance_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class CropHintsAnnotation(proto.Message): + r"""Set of crop hints that are used to generate new crops when + serving images. + + Attributes: + crop_hints (MutableSequence[google.cloud.vision_v1p1beta1.types.CropHint]): + Crop hint results. + """ + + crop_hints: MutableSequence['CropHint'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='CropHint', + ) + + +class CropHintsParams(proto.Message): + r"""Parameters for crop hints annotation request. + + Attributes: + aspect_ratios (MutableSequence[float]): + Aspect ratios in floats, representing the + ratio of the width to the height of the image. + For example, if the desired aspect ratio is 4/3, + the corresponding float value should be 1.33333. + If not specified, the best possible crop is + returned. The number of provided aspect ratios + is limited to a maximum of 16; any aspect ratios + provided after the 16th are ignored. + """ + + aspect_ratios: MutableSequence[float] = proto.RepeatedField( + proto.FLOAT, + number=1, + ) + + +class WebDetectionParams(proto.Message): + r"""Parameters for web detection request. + + Attributes: + include_geo_results (bool): + Whether to include results derived from the + geo information in the image. + """ + + include_geo_results: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class TextDetectionParams(proto.Message): + r"""Parameters for text detections. This is used to control + TEXT_DETECTION and DOCUMENT_TEXT_DETECTION features. + + Attributes: + enable_text_detection_confidence_score (bool): + By default, Cloud Vision API only includes confidence score + for DOCUMENT_TEXT_DETECTION result. Set the flag to true to + include confidence score for TEXT_DETECTION as well. + advanced_ocr_options (MutableSequence[str]): + A list of advanced OCR options to fine-tune + OCR behavior. + """ + + enable_text_detection_confidence_score: bool = proto.Field( + proto.BOOL, + number=9, + ) + advanced_ocr_options: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + + +class ImageContext(proto.Message): + r"""Image context and/or feature-specific parameters. + + Attributes: + lat_long_rect (google.cloud.vision_v1p1beta1.types.LatLongRect): + lat/long rectangle that specifies the + location of the image. + language_hints (MutableSequence[str]): + List of languages to use for TEXT_DETECTION. In most cases, + an empty value yields the best results since it enables + automatic language detection. For languages based on the + Latin alphabet, setting ``language_hints`` is not needed. In + rare cases, when the language of the text in the image is + known, setting a hint will help get better results (although + it will be a significant hindrance if the hint is wrong). + Text detection returns an error if one or more of the + specified languages is not one of the `supported + languages `__. + crop_hints_params (google.cloud.vision_v1p1beta1.types.CropHintsParams): + Parameters for crop hints annotation request. + web_detection_params (google.cloud.vision_v1p1beta1.types.WebDetectionParams): + Parameters for web detection. + text_detection_params (google.cloud.vision_v1p1beta1.types.TextDetectionParams): + Parameters for text detection and document + text detection. + """ + + lat_long_rect: 'LatLongRect' = proto.Field( + proto.MESSAGE, + number=1, + message='LatLongRect', + ) + language_hints: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + crop_hints_params: 'CropHintsParams' = proto.Field( + proto.MESSAGE, + number=4, + message='CropHintsParams', + ) + web_detection_params: 'WebDetectionParams' = proto.Field( + proto.MESSAGE, + number=6, + message='WebDetectionParams', + ) + text_detection_params: 'TextDetectionParams' = proto.Field( + proto.MESSAGE, + number=12, + message='TextDetectionParams', + ) + + +class AnnotateImageRequest(proto.Message): + r"""Request for performing Google Cloud Vision API tasks over a + user-provided image, with user-requested features. + + Attributes: + image (google.cloud.vision_v1p1beta1.types.Image): + The image to be processed. + features (MutableSequence[google.cloud.vision_v1p1beta1.types.Feature]): + Requested features. + image_context (google.cloud.vision_v1p1beta1.types.ImageContext): + Additional context that may accompany the + image. + """ + + image: 'Image' = proto.Field( + proto.MESSAGE, + number=1, + message='Image', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + + +class AnnotateImageResponse(proto.Message): + r"""Response to an image annotation request. + + Attributes: + face_annotations (MutableSequence[google.cloud.vision_v1p1beta1.types.FaceAnnotation]): + If present, face detection has completed + successfully. + landmark_annotations (MutableSequence[google.cloud.vision_v1p1beta1.types.EntityAnnotation]): + If present, landmark detection has completed + successfully. + logo_annotations (MutableSequence[google.cloud.vision_v1p1beta1.types.EntityAnnotation]): + If present, logo detection has completed + successfully. + label_annotations (MutableSequence[google.cloud.vision_v1p1beta1.types.EntityAnnotation]): + If present, label detection has completed + successfully. + text_annotations (MutableSequence[google.cloud.vision_v1p1beta1.types.EntityAnnotation]): + If present, text (OCR) detection has + completed successfully. + full_text_annotation (google.cloud.vision_v1p1beta1.types.TextAnnotation): + If present, text (OCR) detection or document + (OCR) text detection has completed successfully. + This annotation provides the structural + hierarchy for the OCR detected text. + safe_search_annotation (google.cloud.vision_v1p1beta1.types.SafeSearchAnnotation): + If present, safe-search annotation has + completed successfully. + image_properties_annotation (google.cloud.vision_v1p1beta1.types.ImageProperties): + If present, image properties were extracted + successfully. + crop_hints_annotation (google.cloud.vision_v1p1beta1.types.CropHintsAnnotation): + If present, crop hints have completed + successfully. + web_detection (google.cloud.vision_v1p1beta1.types.WebDetection): + If present, web detection has completed + successfully. + error (google.rpc.status_pb2.Status): + If set, represents the error message for the operation. Note + that filled-in image annotations are guaranteed to be + correct, even when ``error`` is set. + """ + + face_annotations: MutableSequence['FaceAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='FaceAnnotation', + ) + landmark_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='EntityAnnotation', + ) + logo_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='EntityAnnotation', + ) + label_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='EntityAnnotation', + ) + text_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='EntityAnnotation', + ) + full_text_annotation: text_annotation.TextAnnotation = proto.Field( + proto.MESSAGE, + number=12, + message=text_annotation.TextAnnotation, + ) + safe_search_annotation: 'SafeSearchAnnotation' = proto.Field( + proto.MESSAGE, + number=6, + message='SafeSearchAnnotation', + ) + image_properties_annotation: 'ImageProperties' = proto.Field( + proto.MESSAGE, + number=8, + message='ImageProperties', + ) + crop_hints_annotation: 'CropHintsAnnotation' = proto.Field( + proto.MESSAGE, + number=11, + message='CropHintsAnnotation', + ) + web_detection: gcv_web_detection.WebDetection = proto.Field( + proto.MESSAGE, + number=13, + message=gcv_web_detection.WebDetection, + ) + error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=9, + message=status_pb2.Status, + ) + + +class BatchAnnotateImagesRequest(proto.Message): + r"""Multiple image annotation requests are batched into a single + service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p1beta1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + """ + + requests: MutableSequence['AnnotateImageRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageRequest', + ) + + +class BatchAnnotateImagesResponse(proto.Message): + r"""Response to a batch image annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1p1beta1.types.AnnotateImageResponse]): + Individual responses to image annotation + requests within the batch. + """ + + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageResponse', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/text_annotation.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/text_annotation.py new file mode 100644 index 00000000..8ec566e3 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/text_annotation.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p1beta1.types import geometry + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p1beta1', + manifest={ + 'TextAnnotation', + 'Page', + 'Block', + 'Paragraph', + 'Word', + 'Symbol', + }, +) + + +class TextAnnotation(proto.Message): + r"""TextAnnotation contains a structured representation of OCR extracted + text. The hierarchy of an OCR extracted text structure is like this: + TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol Each + structural component, starting from Page, may further have their own + properties. Properties describe detected languages, breaks etc.. + Please refer to the + [TextAnnotation.TextProperty][google.cloud.vision.v1p1beta1.TextAnnotation.TextProperty] + message definition below for more detail. + + Attributes: + pages (MutableSequence[google.cloud.vision_v1p1beta1.types.Page]): + List of pages detected by OCR. + text (str): + UTF-8 text detected on the pages. + """ + + class DetectedLanguage(proto.Message): + r"""Detected language for a structural component. + + Attributes: + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + confidence (float): + Confidence of detected language. Range [0, 1]. + """ + + language_code: str = proto.Field( + proto.STRING, + number=1, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class DetectedBreak(proto.Message): + r"""Detected start or end of a structural component. + + Attributes: + type_ (google.cloud.vision_v1p1beta1.types.TextAnnotation.DetectedBreak.BreakType): + Detected break type. + is_prefix (bool): + True if break prepends the element. + """ + class BreakType(proto.Enum): + r"""Enum to denote the type of break found. New line, space etc. + + Values: + UNKNOWN (0): + Unknown break label type. + SPACE (1): + Regular space. + SURE_SPACE (2): + Sure space (very wide). + EOL_SURE_SPACE (3): + Line-wrapping break. + HYPHEN (4): + End-line hyphen that is not present in text; does not + co-occur with ``SPACE``, ``LEADER_SPACE``, or + ``LINE_BREAK``. + LINE_BREAK (5): + Line break that ends a paragraph. + """ + UNKNOWN = 0 + SPACE = 1 + SURE_SPACE = 2 + EOL_SURE_SPACE = 3 + HYPHEN = 4 + LINE_BREAK = 5 + + type_: 'TextAnnotation.DetectedBreak.BreakType' = proto.Field( + proto.ENUM, + number=1, + enum='TextAnnotation.DetectedBreak.BreakType', + ) + is_prefix: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class TextProperty(proto.Message): + r"""Additional information detected on the structural component. + + Attributes: + detected_languages (MutableSequence[google.cloud.vision_v1p1beta1.types.TextAnnotation.DetectedLanguage]): + A list of detected languages together with + confidence. + detected_break (google.cloud.vision_v1p1beta1.types.TextAnnotation.DetectedBreak): + Detected start or end of a text segment. + """ + + detected_languages: MutableSequence['TextAnnotation.DetectedLanguage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='TextAnnotation.DetectedLanguage', + ) + detected_break: 'TextAnnotation.DetectedBreak' = proto.Field( + proto.MESSAGE, + number=2, + message='TextAnnotation.DetectedBreak', + ) + + pages: MutableSequence['Page'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Page', + ) + text: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Page(proto.Message): + r"""Detected page from OCR. + + Attributes: + property (google.cloud.vision_v1p1beta1.types.TextAnnotation.TextProperty): + Additional information detected on the page. + width (int): + Page width in pixels. + height (int): + Page height in pixels. + blocks (MutableSequence[google.cloud.vision_v1p1beta1.types.Block]): + List of blocks of text, images etc on this + page. + confidence (float): + Confidence of the OCR results on the page. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + width: int = proto.Field( + proto.INT32, + number=2, + ) + height: int = proto.Field( + proto.INT32, + number=3, + ) + blocks: MutableSequence['Block'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='Block', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Block(proto.Message): + r"""Logical element on the page. + + Attributes: + property (google.cloud.vision_v1p1beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + block. + bounding_box (google.cloud.vision_v1p1beta1.types.BoundingPoly): + The bounding box for the block. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + paragraphs (MutableSequence[google.cloud.vision_v1p1beta1.types.Paragraph]): + List of paragraphs in this block (if this + blocks is of type text). + block_type (google.cloud.vision_v1p1beta1.types.Block.BlockType): + Detected block type (text, image etc) for + this block. + confidence (float): + Confidence of the OCR results on the block. Range [0, 1]. + """ + class BlockType(proto.Enum): + r"""Type of a block (text, image etc) as identified by OCR. + + Values: + UNKNOWN (0): + Unknown block type. + TEXT (1): + Regular text block. + TABLE (2): + Table block. + PICTURE (3): + Image block. + RULER (4): + Horizontal/vertical line box. + BARCODE (5): + Barcode block. + """ + UNKNOWN = 0 + TEXT = 1 + TABLE = 2 + PICTURE = 3 + RULER = 4 + BARCODE = 5 + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + paragraphs: MutableSequence['Paragraph'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Paragraph', + ) + block_type: BlockType = proto.Field( + proto.ENUM, + number=4, + enum=BlockType, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Paragraph(proto.Message): + r"""Structural unit of text representing a number of words in + certain order. + + Attributes: + property (google.cloud.vision_v1p1beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + paragraph. + bounding_box (google.cloud.vision_v1p1beta1.types.BoundingPoly): + The bounding box for the paragraph. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + words (MutableSequence[google.cloud.vision_v1p1beta1.types.Word]): + List of words in this paragraph. + confidence (float): + Confidence of the OCR results for the paragraph. Range [0, + 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + words: MutableSequence['Word'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Word', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Word(proto.Message): + r"""A word representation. + + Attributes: + property (google.cloud.vision_v1p1beta1.types.TextAnnotation.TextProperty): + Additional information detected for the word. + bounding_box (google.cloud.vision_v1p1beta1.types.BoundingPoly): + The bounding box for the word. The vertices are in the order + of top-left, top-right, bottom-right, bottom-left. When a + rotation of the bounding box is detected the rotation is + represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + symbols (MutableSequence[google.cloud.vision_v1p1beta1.types.Symbol]): + List of symbols in the word. + The order of the symbols follows the natural + reading order. + confidence (float): + Confidence of the OCR results for the word. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + symbols: MutableSequence['Symbol'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Symbol', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Symbol(proto.Message): + r"""A single symbol representation. + + Attributes: + property (google.cloud.vision_v1p1beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + symbol. + bounding_box (google.cloud.vision_v1p1beta1.types.BoundingPoly): + The bounding box for the symbol. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + text (str): + The actual UTF-8 representation of the + symbol. + confidence (float): + Confidence of the OCR results for the symbol. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + text: str = proto.Field( + proto.STRING, + number=3, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/web_detection.py b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/web_detection.py new file mode 100644 index 00000000..e7e2f1ed --- /dev/null +++ b/owl-bot-staging/v1p1beta1/google/cloud/vision_v1p1beta1/types/web_detection.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p1beta1', + manifest={ + 'WebDetection', + }, +) + + +class WebDetection(proto.Message): + r"""Relevant information for the image from the Internet. + + Attributes: + web_entities (MutableSequence[google.cloud.vision_v1p1beta1.types.WebDetection.WebEntity]): + Deduced entities from similar images on the + Internet. + full_matching_images (MutableSequence[google.cloud.vision_v1p1beta1.types.WebDetection.WebImage]): + Fully matching images from the Internet. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1p1beta1.types.WebDetection.WebImage]): + Partial matching images from the Internet. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + pages_with_matching_images (MutableSequence[google.cloud.vision_v1p1beta1.types.WebDetection.WebPage]): + Web pages containing the matching images from + the Internet. + visually_similar_images (MutableSequence[google.cloud.vision_v1p1beta1.types.WebDetection.WebImage]): + The visually similar image results. + best_guess_labels (MutableSequence[google.cloud.vision_v1p1beta1.types.WebDetection.WebLabel]): + Best guess text labels for the request image. + """ + + class WebEntity(proto.Message): + r"""Entity deduced from similar images on the Internet. + + Attributes: + entity_id (str): + Opaque entity ID. + score (float): + Overall relevancy score for the entity. + Not normalized and not comparable across + different image queries. + description (str): + Canonical description of the entity, in + English. + """ + + entity_id: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + + class WebImage(proto.Message): + r"""Metadata for online images. + + Attributes: + url (str): + The result image URL. + score (float): + (Deprecated) Overall relevancy score for the + image. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class WebPage(proto.Message): + r"""Metadata for web pages. + + Attributes: + url (str): + The result web page URL. + score (float): + (Deprecated) Overall relevancy score for the + web page. + page_title (str): + Title for the web page, may contain HTML + markups. + full_matching_images (MutableSequence[google.cloud.vision_v1p1beta1.types.WebDetection.WebImage]): + Fully matching images on the page. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1p1beta1.types.WebDetection.WebImage]): + Partial matching images on the page. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + page_title: str = proto.Field( + proto.STRING, + number=3, + ) + full_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='WebDetection.WebImage', + ) + partial_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='WebDetection.WebImage', + ) + + class WebLabel(proto.Message): + r"""Label to provide extra metadata for the web detection. + + Attributes: + label (str): + Label for extra metadata. + language_code (str): + The BCP-47 language code for ``label``, such as "en-US" or + "sr-Latn". For more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + """ + + label: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + + web_entities: MutableSequence[WebEntity] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=WebEntity, + ) + full_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=WebImage, + ) + partial_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=WebImage, + ) + pages_with_matching_images: MutableSequence[WebPage] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=WebPage, + ) + visually_similar_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=WebImage, + ) + best_guess_labels: MutableSequence[WebLabel] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=WebLabel, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p1beta1/mypy.ini b/owl-bot-staging/v1p1beta1/mypy.ini new file mode 100644 index 00000000..574c5aed --- /dev/null +++ b/owl-bot-staging/v1p1beta1/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/v1p1beta1/noxfile.py b/owl-bot-staging/v1p1beta1/noxfile.py new file mode 100644 index 00000000..6a68da8e --- /dev/null +++ b/owl-bot-staging/v1p1beta1/noxfile.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +import pathlib +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = subprocess.check_output([sys.executable, "setup.py", "--name"], encoding="utf-8") + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.11" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "lint_setup_py", +] + +@nox.session(python=ALL_PYTHON) +def unit(session): + """Run the unit test suite.""" + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.') + + session.run( + 'py.test', + '--quiet', + '--cov=google/cloud/vision_v1p1beta1/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)) + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + session.install( + 'mypy', + 'types-requests', + 'types-protobuf' + ) + session.install('.') + session.run( + 'mypy', + '--explicit-package-bases', + 'google', + ) + + +@nox.session +def update_lower_bounds(session): + """Update lower bounds in constraints.txt to match setup.py""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'update', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + + +@nox.session +def check_lower_bounds(session): + """Check lower bounds in setup.py are reflected in constraints file""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'check', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install("sphinx==7.0.1", "alabaster", "recommonmark") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", BLACK_VERSION) + session.run( + "black", + "--check", + *BLACK_PATHS, + ) + session.run("flake8", "google", "tests", "samples") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *BLACK_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") diff --git a/owl-bot-staging/v1p1beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json b/owl-bot-staging/v1p1beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json new file mode 100644 index 00000000..70f20c5e --- /dev/null +++ b/owl-bot-staging/v1p1beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p1beta1.json @@ -0,0 +1,176 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.vision.v1p1beta1", + "version": "v1p1beta1" + } + ], + "language": "PYTHON", + "name": "google-cloud-vision", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p1beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p1beta1.ImageAnnotatorAsyncClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p1beta1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p1beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p1beta1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p1beta1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p1beta1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1p1beta1_generated_image_annotator_batch_annotate_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p1beta1_generated_ImageAnnotator_BatchAnnotateImages_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p1beta1_generated_image_annotator_batch_annotate_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p1beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p1beta1.ImageAnnotatorClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p1beta1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p1beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p1beta1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p1beta1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p1beta1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1p1beta1_generated_image_annotator_batch_annotate_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p1beta1_generated_ImageAnnotator_BatchAnnotateImages_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p1beta1_generated_image_annotator_batch_annotate_images_sync.py" + } + ] +} diff --git a/owl-bot-staging/v1p1beta1/samples/generated_samples/vision_v1p1beta1_generated_image_annotator_batch_annotate_images_async.py b/owl-bot-staging/v1p1beta1/samples/generated_samples/vision_v1p1beta1_generated_image_annotator_batch_annotate_images_async.py new file mode 100644 index 00000000..075ca057 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/samples/generated_samples/vision_v1p1beta1_generated_image_annotator_batch_annotate_images_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p1beta1_generated_ImageAnnotator_BatchAnnotateImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p1beta1 + + +async def sample_batch_annotate_images(): + # Create a client + client = vision_v1p1beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p1beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1p1beta1_generated_ImageAnnotator_BatchAnnotateImages_async] diff --git a/owl-bot-staging/v1p1beta1/samples/generated_samples/vision_v1p1beta1_generated_image_annotator_batch_annotate_images_sync.py b/owl-bot-staging/v1p1beta1/samples/generated_samples/vision_v1p1beta1_generated_image_annotator_batch_annotate_images_sync.py new file mode 100644 index 00000000..f0b781f0 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/samples/generated_samples/vision_v1p1beta1_generated_image_annotator_batch_annotate_images_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p1beta1_generated_ImageAnnotator_BatchAnnotateImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p1beta1 + + +def sample_batch_annotate_images(): + # Create a client + client = vision_v1p1beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p1beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1p1beta1_generated_ImageAnnotator_BatchAnnotateImages_sync] diff --git a/owl-bot-staging/v1p1beta1/scripts/fixup_vision_v1p1beta1_keywords.py b/owl-bot-staging/v1p1beta1/scripts/fixup_vision_v1p1beta1_keywords.py new file mode 100644 index 00000000..978efe99 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/scripts/fixup_vision_v1p1beta1_keywords.py @@ -0,0 +1,176 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class visionCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'batch_annotate_images': ('requests', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=visionCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the vision client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/owl-bot-staging/v1p1beta1/setup.py b/owl-bot-staging/v1p1beta1/setup.py new file mode 100644 index 00000000..7525c907 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/setup.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import io +import os + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-cloud-vision' + + +description = "Google Cloud Vision API client library" + +version = {} +with open(os.path.join(package_root, 'google/cloud/vision/gapic_version.py')) as fp: + exec(fp.read(), version) +version = version["__version__"] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.0, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "proto-plus >= 1.22.0, <2.0.0dev", + "proto-plus >= 1.22.2, <2.0.0dev; python_version>='3.11'", + "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/python-vision" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.PEP420PackageFinder.find() + if package.startswith("google") +] + +namespaces = ["google", "google.cloud"] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + namespace_packages=namespaces, + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/v1p1beta1/testing/constraints-3.10.txt b/owl-bot-staging/v1p1beta1/testing/constraints-3.10.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p1beta1/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p1beta1/testing/constraints-3.11.txt b/owl-bot-staging/v1p1beta1/testing/constraints-3.11.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p1beta1/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p1beta1/testing/constraints-3.12.txt b/owl-bot-staging/v1p1beta1/testing/constraints-3.12.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p1beta1/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p1beta1/testing/constraints-3.7.txt b/owl-bot-staging/v1p1beta1/testing/constraints-3.7.txt new file mode 100644 index 00000000..6c44adfe --- /dev/null +++ b/owl-bot-staging/v1p1beta1/testing/constraints-3.7.txt @@ -0,0 +1,9 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file. +# Pin the version to the lower bound. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", +# Then this file should have google-cloud-foo==1.14.0 +google-api-core==1.34.0 +proto-plus==1.22.0 +protobuf==3.19.5 diff --git a/owl-bot-staging/v1p1beta1/testing/constraints-3.8.txt b/owl-bot-staging/v1p1beta1/testing/constraints-3.8.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p1beta1/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p1beta1/testing/constraints-3.9.txt b/owl-bot-staging/v1p1beta1/testing/constraints-3.9.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p1beta1/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p1beta1/tests/__init__.py b/owl-bot-staging/v1p1beta1/tests/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p1beta1/tests/unit/__init__.py b/owl-bot-staging/v1p1beta1/tests/unit/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p1beta1/tests/unit/gapic/__init__.py b/owl-bot-staging/v1p1beta1/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p1beta1/tests/unit/gapic/vision_v1p1beta1/__init__.py b/owl-bot-staging/v1p1beta1/tests/unit/gapic/vision_v1p1beta1/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/tests/unit/gapic/vision_v1p1beta1/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p1beta1/tests/unit/gapic/vision_v1p1beta1/test_image_annotator.py b/owl-bot-staging/v1p1beta1/tests/unit/gapic/vision_v1p1beta1/test_image_annotator.py new file mode 100644 index 00000000..48529c98 --- /dev/null +++ b/owl-bot-staging/v1p1beta1/tests/unit/gapic/vision_v1p1beta1/test_image_annotator.py @@ -0,0 +1,1596 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule +from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.vision_v1p1beta1.services.image_annotator import ImageAnnotatorAsyncClient +from google.cloud.vision_v1p1beta1.services.image_annotator import ImageAnnotatorClient +from google.cloud.vision_v1p1beta1.services.image_annotator import transports +from google.cloud.vision_v1p1beta1.types import image_annotator +from google.oauth2 import service_account +from google.type import latlng_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ImageAnnotatorClient._get_default_mtls_endpoint(None) is None + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ImageAnnotatorGrpcTransport, "grpc"), + (transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +def test_image_annotator_client_get_transport_class(): + transport = ImageAnnotatorClient.get_transport_class() + available_transports = [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorRestTransport, + ] + assert transport in available_transports + + transport = ImageAnnotatorClient.get_transport_class("grpc") + assert transport == transports.ImageAnnotatorGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "true"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "false"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "false"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_image_annotator_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + ImageAnnotatorClient, ImageAnnotatorAsyncClient +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", None), +]) +def test_image_annotator_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_image_annotator_client_client_options_from_dict(): + with mock.patch('google.cloud.vision_v1p1beta1.services.image_annotator.transports.ImageAnnotatorGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ImageAnnotatorClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_image_annotator_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=None, + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse( + ) + response = client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + client.batch_annotate_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + +@pytest.mark.asyncio +async def test_batch_annotate_images_async(transport: str = 'grpc_asyncio', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse( + )) + response = await client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +@pytest.mark.asyncio +async def test_batch_annotate_images_async_from_dict(): + await test_batch_annotate_images_async(request_type=dict) + + +def test_batch_annotate_images_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + + +def test_batch_annotate_images_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_annotate_images(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_rest_required_fields(request_type=image_annotator.BatchAnnotateImagesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_annotate_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_annotate_images_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_annotate_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_annotate_images_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_batch_annotate_images") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_batch_annotate_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.BatchAnnotateImagesRequest.pb(image_annotator.BatchAnnotateImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = image_annotator.BatchAnnotateImagesResponse.to_json(image_annotator.BatchAnnotateImagesResponse()) + + request = image_annotator.BatchAnnotateImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = image_annotator.BatchAnnotateImagesResponse() + + client.batch_annotate_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_annotate_images_rest_bad_request(transport: str = 'rest', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.batch_annotate_images(request) + + +def test_batch_annotate_images_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_annotate_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p1beta1/images:annotate" % client.transport._host, args[1]) + + +def test_batch_annotate_images_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +def test_batch_annotate_images_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ImageAnnotatorClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "rest", +]) +def test_transport_kind(transport_name): + transport = ImageAnnotatorClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ImageAnnotatorGrpcTransport, + ) + +def test_image_annotator_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_image_annotator_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.vision_v1p1beta1.services.image_annotator.transports.ImageAnnotatorTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'batch_annotate_images', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_image_annotator_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.vision_v1p1beta1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id="octopus", + ) + + +def test_image_annotator_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.vision_v1p1beta1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport() + adc.assert_called_once() + + +def test_image_annotator_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ImageAnnotatorClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + ], +) +def test_image_annotator_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-vision',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, + ], +) +def test_image_annotator_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ImageAnnotatorGrpcTransport, grpc_helpers), + (transports.ImageAnnotatorGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_image_annotator_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=["1", "2"], + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_image_annotator_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel") as mock_configure_mtls_channel: + transports.ImageAnnotatorRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_no_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_with_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_image_annotator_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ImageAnnotatorClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ImageAnnotatorClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.batch_annotate_images._session + session2 = client2.transport.batch_annotate_images._session + assert session1 != session2 +def test_image_annotator_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_image_annotator_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ImageAnnotatorClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = ImageAnnotatorClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder, ) + actual = ImageAnnotatorClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = ImageAnnotatorClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ImageAnnotatorClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = ImageAnnotatorClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project, ) + actual = ImageAnnotatorClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = ImageAnnotatorClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ImageAnnotatorClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = ImageAnnotatorClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + transport_class = ImageAnnotatorClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/owl-bot-staging/v1p2beta1/.coveragerc b/owl-bot-staging/v1p2beta1/.coveragerc new file mode 100644 index 00000000..cbf0b85a --- /dev/null +++ b/owl-bot-staging/v1p2beta1/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/vision/__init__.py + google/cloud/vision/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/owl-bot-staging/v1p2beta1/.flake8 b/owl-bot-staging/v1p2beta1/.flake8 new file mode 100644 index 00000000..29227d4c --- /dev/null +++ b/owl-bot-staging/v1p2beta1/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2020 Google LLC +# +# Licensed 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 +# +# https://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. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/owl-bot-staging/v1p2beta1/MANIFEST.in b/owl-bot-staging/v1p2beta1/MANIFEST.in new file mode 100644 index 00000000..397ad4e2 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/vision *.py +recursive-include google/cloud/vision_v1p2beta1 *.py diff --git a/owl-bot-staging/v1p2beta1/README.rst b/owl-bot-staging/v1p2beta1/README.rst new file mode 100644 index 00000000..39f9ca72 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Vision API +================================================= + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. Enable the Google Cloud Vision API. +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a `virtualenv`_ using pip. `virtualenv`_ is a tool to +create isolated Python environments. The basic problem it addresses is one of +dependencies and versions, and indirectly permissions. + +With `virtualenv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ + + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + /bin/pip install /path/to/library + + +Windows +^^^^^^^ + +.. code-block:: console + + python3 -m venv + \Scripts\activate + \Scripts\pip.exe install \path\to\library diff --git a/owl-bot-staging/v1p2beta1/docs/_static/custom.css b/owl-bot-staging/v1p2beta1/docs/_static/custom.css new file mode 100644 index 00000000..06423be0 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/v1p2beta1/docs/conf.py b/owl-bot-staging/v1p2beta1/docs/conf.py new file mode 100644 index 00000000..c75f569a --- /dev/null +++ b/owl-bot-staging/v1p2beta1/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# +# google-cloud-vision documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import shlex + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +__version__ = "0.1.0" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.0.1" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_flags = ["members"] +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# Allow markdown includes (so releases.md can include CHANGLEOG.md) +# http://www.sphinx-doc.org/en/master/markdown.html +source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = u"google-cloud-vision" +copyright = u"2023, Google, LLC" +author = u"Google APIs" # TODO: autogenerate this bit + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for Python", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-cloud-vision-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', + # Latex figure (float) alignment + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + root_doc, + "google-cloud-vision.tex", + u"google-cloud-vision Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + root_doc, + "google-cloud-vision", + u"Google Cloud Vision Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + root_doc, + "google-cloud-vision", + u"google-cloud-vision Documentation", + author, + "google-cloud-vision", + "GAPIC library for Google Cloud Vision API", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("http://python.readthedocs.org/en/latest/", None), + "gax": ("https://gax-python.readthedocs.org/en/latest/", None), + "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), + "google-gax": ("https://gax-python.readthedocs.io/en/latest/", None), + "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None), + "grpc": ("https://grpc.io/grpc/python/", None), + "requests": ("http://requests.kennethreitz.org/en/stable/", None), + "proto": ("https://proto-plus-python.readthedocs.io/en/stable", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/owl-bot-staging/v1p2beta1/docs/index.rst b/owl-bot-staging/v1p2beta1/docs/index.rst new file mode 100644 index 00000000..d7cb733f --- /dev/null +++ b/owl-bot-staging/v1p2beta1/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + vision_v1p2beta1/services + vision_v1p2beta1/types diff --git a/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/image_annotator.rst b/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/image_annotator.rst new file mode 100644 index 00000000..d05fd549 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/image_annotator.rst @@ -0,0 +1,6 @@ +ImageAnnotator +-------------------------------- + +.. automodule:: google.cloud.vision_v1p2beta1.services.image_annotator + :members: + :inherited-members: diff --git a/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/services.rst b/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/services.rst new file mode 100644 index 00000000..2272ceb5 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/services.rst @@ -0,0 +1,6 @@ +Services for Google Cloud Vision v1p2beta1 API +============================================== +.. toctree:: + :maxdepth: 2 + + image_annotator diff --git a/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/types.rst b/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/types.rst new file mode 100644 index 00000000..898a797f --- /dev/null +++ b/owl-bot-staging/v1p2beta1/docs/vision_v1p2beta1/types.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Vision v1p2beta1 API +=========================================== + +.. automodule:: google.cloud.vision_v1p2beta1.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision/__init__.py b/owl-bot-staging/v1p2beta1/google/cloud/vision/__init__.py new file mode 100644 index 00000000..4d92c234 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision/__init__.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.vision_v1p2beta1.services.image_annotator.client import ImageAnnotatorClient +from google.cloud.vision_v1p2beta1.services.image_annotator.async_client import ImageAnnotatorAsyncClient + +from google.cloud.vision_v1p2beta1.types.geometry import BoundingPoly +from google.cloud.vision_v1p2beta1.types.geometry import NormalizedVertex +from google.cloud.vision_v1p2beta1.types.geometry import Position +from google.cloud.vision_v1p2beta1.types.geometry import Vertex +from google.cloud.vision_v1p2beta1.types.image_annotator import AnnotateFileResponse +from google.cloud.vision_v1p2beta1.types.image_annotator import AnnotateImageRequest +from google.cloud.vision_v1p2beta1.types.image_annotator import AnnotateImageResponse +from google.cloud.vision_v1p2beta1.types.image_annotator import AsyncAnnotateFileRequest +from google.cloud.vision_v1p2beta1.types.image_annotator import AsyncAnnotateFileResponse +from google.cloud.vision_v1p2beta1.types.image_annotator import AsyncBatchAnnotateFilesRequest +from google.cloud.vision_v1p2beta1.types.image_annotator import AsyncBatchAnnotateFilesResponse +from google.cloud.vision_v1p2beta1.types.image_annotator import BatchAnnotateImagesRequest +from google.cloud.vision_v1p2beta1.types.image_annotator import BatchAnnotateImagesResponse +from google.cloud.vision_v1p2beta1.types.image_annotator import ColorInfo +from google.cloud.vision_v1p2beta1.types.image_annotator import CropHint +from google.cloud.vision_v1p2beta1.types.image_annotator import CropHintsAnnotation +from google.cloud.vision_v1p2beta1.types.image_annotator import CropHintsParams +from google.cloud.vision_v1p2beta1.types.image_annotator import DominantColorsAnnotation +from google.cloud.vision_v1p2beta1.types.image_annotator import EntityAnnotation +from google.cloud.vision_v1p2beta1.types.image_annotator import FaceAnnotation +from google.cloud.vision_v1p2beta1.types.image_annotator import Feature +from google.cloud.vision_v1p2beta1.types.image_annotator import GcsDestination +from google.cloud.vision_v1p2beta1.types.image_annotator import GcsSource +from google.cloud.vision_v1p2beta1.types.image_annotator import Image +from google.cloud.vision_v1p2beta1.types.image_annotator import ImageAnnotationContext +from google.cloud.vision_v1p2beta1.types.image_annotator import ImageContext +from google.cloud.vision_v1p2beta1.types.image_annotator import ImageProperties +from google.cloud.vision_v1p2beta1.types.image_annotator import ImageSource +from google.cloud.vision_v1p2beta1.types.image_annotator import InputConfig +from google.cloud.vision_v1p2beta1.types.image_annotator import LatLongRect +from google.cloud.vision_v1p2beta1.types.image_annotator import LocationInfo +from google.cloud.vision_v1p2beta1.types.image_annotator import OperationMetadata +from google.cloud.vision_v1p2beta1.types.image_annotator import OutputConfig +from google.cloud.vision_v1p2beta1.types.image_annotator import Property +from google.cloud.vision_v1p2beta1.types.image_annotator import SafeSearchAnnotation +from google.cloud.vision_v1p2beta1.types.image_annotator import TextDetectionParams +from google.cloud.vision_v1p2beta1.types.image_annotator import WebDetectionParams +from google.cloud.vision_v1p2beta1.types.image_annotator import Likelihood +from google.cloud.vision_v1p2beta1.types.text_annotation import Block +from google.cloud.vision_v1p2beta1.types.text_annotation import Page +from google.cloud.vision_v1p2beta1.types.text_annotation import Paragraph +from google.cloud.vision_v1p2beta1.types.text_annotation import Symbol +from google.cloud.vision_v1p2beta1.types.text_annotation import TextAnnotation +from google.cloud.vision_v1p2beta1.types.text_annotation import Word +from google.cloud.vision_v1p2beta1.types.web_detection import WebDetection + +__all__ = ('ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', + 'BoundingPoly', + 'NormalizedVertex', + 'Position', + 'Vertex', + 'AnnotateFileResponse', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'GcsDestination', + 'GcsSource', + 'Image', + 'ImageAnnotationContext', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'InputConfig', + 'LatLongRect', + 'LocationInfo', + 'OperationMetadata', + 'OutputConfig', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision/gapic_version.py b/owl-bot-staging/v1p2beta1/google/cloud/vision/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision/py.typed b/owl-bot-staging/v1p2beta1/google/cloud/vision/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/__init__.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/__init__.py new file mode 100644 index 00000000..123bd57c --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/__init__.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision_v1p2beta1 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.image_annotator import ImageAnnotatorClient +from .services.image_annotator import ImageAnnotatorAsyncClient + +from .types.geometry import BoundingPoly +from .types.geometry import NormalizedVertex +from .types.geometry import Position +from .types.geometry import Vertex +from .types.image_annotator import AnnotateFileResponse +from .types.image_annotator import AnnotateImageRequest +from .types.image_annotator import AnnotateImageResponse +from .types.image_annotator import AsyncAnnotateFileRequest +from .types.image_annotator import AsyncAnnotateFileResponse +from .types.image_annotator import AsyncBatchAnnotateFilesRequest +from .types.image_annotator import AsyncBatchAnnotateFilesResponse +from .types.image_annotator import BatchAnnotateImagesRequest +from .types.image_annotator import BatchAnnotateImagesResponse +from .types.image_annotator import ColorInfo +from .types.image_annotator import CropHint +from .types.image_annotator import CropHintsAnnotation +from .types.image_annotator import CropHintsParams +from .types.image_annotator import DominantColorsAnnotation +from .types.image_annotator import EntityAnnotation +from .types.image_annotator import FaceAnnotation +from .types.image_annotator import Feature +from .types.image_annotator import GcsDestination +from .types.image_annotator import GcsSource +from .types.image_annotator import Image +from .types.image_annotator import ImageAnnotationContext +from .types.image_annotator import ImageContext +from .types.image_annotator import ImageProperties +from .types.image_annotator import ImageSource +from .types.image_annotator import InputConfig +from .types.image_annotator import LatLongRect +from .types.image_annotator import LocationInfo +from .types.image_annotator import OperationMetadata +from .types.image_annotator import OutputConfig +from .types.image_annotator import Property +from .types.image_annotator import SafeSearchAnnotation +from .types.image_annotator import TextDetectionParams +from .types.image_annotator import WebDetectionParams +from .types.image_annotator import Likelihood +from .types.text_annotation import Block +from .types.text_annotation import Page +from .types.text_annotation import Paragraph +from .types.text_annotation import Symbol +from .types.text_annotation import TextAnnotation +from .types.text_annotation import Word +from .types.web_detection import WebDetection + +__all__ = ( + 'ImageAnnotatorAsyncClient', +'AnnotateFileResponse', +'AnnotateImageRequest', +'AnnotateImageResponse', +'AsyncAnnotateFileRequest', +'AsyncAnnotateFileResponse', +'AsyncBatchAnnotateFilesRequest', +'AsyncBatchAnnotateFilesResponse', +'BatchAnnotateImagesRequest', +'BatchAnnotateImagesResponse', +'Block', +'BoundingPoly', +'ColorInfo', +'CropHint', +'CropHintsAnnotation', +'CropHintsParams', +'DominantColorsAnnotation', +'EntityAnnotation', +'FaceAnnotation', +'Feature', +'GcsDestination', +'GcsSource', +'Image', +'ImageAnnotationContext', +'ImageAnnotatorClient', +'ImageContext', +'ImageProperties', +'ImageSource', +'InputConfig', +'LatLongRect', +'Likelihood', +'LocationInfo', +'NormalizedVertex', +'OperationMetadata', +'OutputConfig', +'Page', +'Paragraph', +'Position', +'Property', +'SafeSearchAnnotation', +'Symbol', +'TextAnnotation', +'TextDetectionParams', +'Vertex', +'WebDetection', +'WebDetectionParams', +'Word', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/gapic_metadata.json b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/gapic_metadata.json new file mode 100644 index 00000000..43257e5d --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/gapic_metadata.json @@ -0,0 +1,58 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.vision_v1p2beta1", + "protoPackage": "google.cloud.vision.v1p2beta1", + "schema": "1.0", + "services": { + "ImageAnnotator": { + "clients": { + "grpc": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ImageAnnotatorAsyncClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "rest": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/gapic_version.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/py.typed b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/__init__.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/__init__.py new file mode 100644 index 00000000..89a37dc9 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/__init__.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/__init__.py new file mode 100644 index 00000000..ee708f26 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .client import ImageAnnotatorClient +from .async_client import ImageAnnotatorAsyncClient + +__all__ = ( + 'ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/async_client.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/async_client.py new file mode 100644 index 00000000..538fd56c --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/async_client.py @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.vision_v1p2beta1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p2beta1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .client import ImageAnnotatorClient + + +class ImageAnnotatorAsyncClient: + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + _client: ImageAnnotatorClient + + DEFAULT_ENDPOINT = ImageAnnotatorClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ImageAnnotatorClient.DEFAULT_MTLS_ENDPOINT + + common_billing_account_path = staticmethod(ImageAnnotatorClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ImageAnnotatorClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ImageAnnotatorClient.common_folder_path) + parse_common_folder_path = staticmethod(ImageAnnotatorClient.parse_common_folder_path) + common_organization_path = staticmethod(ImageAnnotatorClient.common_organization_path) + parse_common_organization_path = staticmethod(ImageAnnotatorClient.parse_common_organization_path) + common_project_path = staticmethod(ImageAnnotatorClient.common_project_path) + parse_common_project_path = staticmethod(ImageAnnotatorClient.parse_common_project_path) + common_location_path = staticmethod(ImageAnnotatorClient.common_location_path) + parse_common_location_path = staticmethod(ImageAnnotatorClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_info.__func__(ImageAnnotatorAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_file.__func__(ImageAnnotatorAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ImageAnnotatorClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ImageAnnotatorClient).get_transport_class, type(ImageAnnotatorClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ImageAnnotatorTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ImageAnnotatorClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p2beta1 + + async def sample_batch_annotate_images(): + # Create a client + client = vision_v1p2beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p2beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p2beta1.types.BatchAnnotateImagesRequest, dict]]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (:class:`MutableSequence[google.cloud.vision_v1p2beta1.types.AnnotateImageRequest]`): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p2beta1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.BatchAnnotateImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def async_batch_annotate_files(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AsyncAnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Run async image detection and annotation for a list of generic + files (e.g. PDF) which may contain multiple pages and multiple + images per page. Progress and results can be retrieved through + the ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p2beta1 + + async def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p2beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p2beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p2beta1.types.AsyncBatchAnnotateFilesRequest, dict]]): + The request object. Multiple async file annotation + requests are batched into a single + service call. + requests (:class:`MutableSequence[google.cloud.vision_v1p2beta1.types.AsyncAnnotateFileRequest]`): + Required. Individual async file + annotation requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p2beta1.types.AsyncBatchAnnotateFilesResponse` + Response to an async batch file annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.AsyncBatchAnnotateFilesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.async_batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + image_annotator.AsyncBatchAnnotateFilesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ImageAnnotatorAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorAsyncClient", +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/client.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/client.py new file mode 100644 index 00000000..13c26bb3 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/client.py @@ -0,0 +1,603 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import os +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast + +from google.cloud.vision_v1p2beta1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p2beta1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ImageAnnotatorGrpcTransport +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .transports.rest import ImageAnnotatorRestTransport + + +class ImageAnnotatorClientMeta(type): + """Metaclass for the ImageAnnotator client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] + _transport_registry["grpc"] = ImageAnnotatorGrpcTransport + _transport_registry["grpc_asyncio"] = ImageAnnotatorGrpcAsyncIOTransport + _transport_registry["rest"] = ImageAnnotatorRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ImageAnnotatorTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ImageAnnotatorClient(metaclass=ImageAnnotatorClientMeta): + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "vision.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ImageAnnotatorTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ImageAnnotatorTransport): + # transport is a ImageAnnotatorTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p2beta1 + + def sample_batch_annotate_images(): + # Create a client + client = vision_v1p2beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p2beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p2beta1.types.BatchAnnotateImagesRequest, dict]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (MutableSequence[google.cloud.vision_v1p2beta1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p2beta1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.BatchAnnotateImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.BatchAnnotateImagesRequest): + request = image_annotator.BatchAnnotateImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_annotate_images] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def async_batch_annotate_files(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AsyncAnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Run async image detection and annotation for a list of generic + files (e.g. PDF) which may contain multiple pages and multiple + images per page. Progress and results can be retrieved through + the ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p2beta1 + + def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p2beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p2beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p2beta1.types.AsyncBatchAnnotateFilesRequest, dict]): + The request object. Multiple async file annotation + requests are batched into a single + service call. + requests (MutableSequence[google.cloud.vision_v1p2beta1.types.AsyncAnnotateFileRequest]): + Required. Individual async file + annotation requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p2beta1.types.AsyncBatchAnnotateFilesResponse` + Response to an async batch file annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.AsyncBatchAnnotateFilesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.AsyncBatchAnnotateFilesRequest): + request = image_annotator.AsyncBatchAnnotateFilesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.async_batch_annotate_files] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + image_annotator.AsyncBatchAnnotateFilesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ImageAnnotatorClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorClient", +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/__init__.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/__init__.py new file mode 100644 index 00000000..ad6cf948 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +from typing import Dict, Type + +from .base import ImageAnnotatorTransport +from .grpc import ImageAnnotatorGrpcTransport +from .grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .rest import ImageAnnotatorRestTransport +from .rest import ImageAnnotatorRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] +_transport_registry['grpc'] = ImageAnnotatorGrpcTransport +_transport_registry['grpc_asyncio'] = ImageAnnotatorGrpcAsyncIOTransport +_transport_registry['rest'] = ImageAnnotatorRestTransport + +__all__ = ( + 'ImageAnnotatorTransport', + 'ImageAnnotatorGrpcTransport', + 'ImageAnnotatorGrpcAsyncIOTransport', + 'ImageAnnotatorRestTransport', + 'ImageAnnotatorRestInterceptor', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/base.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/base.py new file mode 100644 index 00000000..f3b3f047 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/base.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.vision_v1p2beta1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.vision_v1p2beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ImageAnnotatorTransport(abc.ABC): + """Abstract transport class for ImageAnnotator.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', + ) + + DEFAULT_HOST: str = 'vision.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience(api_audience if api_audience else host) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.batch_annotate_images: gapic_v1.method.wrap_method( + self.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.async_batch_annotate_files: gapic_v1.method.wrap_method( + self.async_batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Union[ + image_annotator.BatchAnnotateImagesResponse, + Awaitable[image_annotator.BatchAnnotateImagesResponse] + ]]: + raise NotImplementedError() + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ImageAnnotatorTransport', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/grpc.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/grpc.py new file mode 100644 index 00000000..4896dc84 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/grpc.py @@ -0,0 +1,319 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.vision_v1p2beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO + + +class ImageAnnotatorGrpcTransport(ImageAnnotatorTransport): + """gRPC backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + ~.BatchAnnotateImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p2beta1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + operations_pb2.Operation]: + r"""Return a callable for the async batch annotate files method over gRPC. + + Run async image detection and annotation for a list of generic + files (e.g. PDF) which may contain multiple pages and multiple + images per page. Progress and results can be retrieved through + the ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + Returns: + Callable[[~.AsyncBatchAnnotateFilesRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_files' not in self._stubs: + self._stubs['async_batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p2beta1.ImageAnnotator/AsyncBatchAnnotateFiles', + request_serializer=image_annotator.AsyncBatchAnnotateFilesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_files'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ImageAnnotatorGrpcTransport', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/grpc_asyncio.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/grpc_asyncio.py new file mode 100644 index 00000000..0ed91d65 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/grpc_asyncio.py @@ -0,0 +1,318 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.vision_v1p2beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .grpc import ImageAnnotatorGrpcTransport + + +class ImageAnnotatorGrpcAsyncIOTransport(ImageAnnotatorTransport): + """gRPC AsyncIO backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Awaitable[image_annotator.BatchAnnotateImagesResponse]]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + Awaitable[~.BatchAnnotateImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p2beta1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the async batch annotate files method over gRPC. + + Run async image detection and annotation for a list of generic + files (e.g. PDF) which may contain multiple pages and multiple + images per page. Progress and results can be retrieved through + the ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + Returns: + Callable[[~.AsyncBatchAnnotateFilesRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_files' not in self._stubs: + self._stubs['async_batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p2beta1.ImageAnnotator/AsyncBatchAnnotateFiles', + request_serializer=image_annotator.AsyncBatchAnnotateFilesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_files'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ImageAnnotatorGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/rest.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/rest.py new file mode 100644 index 00000000..bbdd8889 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/services/image_annotator/transports/rest.py @@ -0,0 +1,454 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.auth.transport.requests import AuthorizedSession # type: ignore +import json # type: ignore +import grpc # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.api_core import rest_helpers +from google.api_core import rest_streaming +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from google.api_core import operations_v1 +from requests import __version__ as requests_version +import dataclasses +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.cloud.vision_v1p2beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore + +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ImageAnnotatorRestInterceptor: + """Interceptor for ImageAnnotator. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ImageAnnotatorRestTransport. + + .. code-block:: python + class MyCustomImageAnnotatorInterceptor(ImageAnnotatorRestInterceptor): + def pre_async_batch_annotate_files(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_async_batch_annotate_files(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_annotate_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_annotate_images(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ImageAnnotatorRestTransport(interceptor=MyCustomImageAnnotatorInterceptor()) + client = ImageAnnotatorClient(transport=transport) + + + """ + def pre_async_batch_annotate_files(self, request: image_annotator.AsyncBatchAnnotateFilesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.AsyncBatchAnnotateFilesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for async_batch_annotate_files + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_async_batch_annotate_files(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for async_batch_annotate_files + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + def pre_batch_annotate_images(self, request: image_annotator.BatchAnnotateImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.BatchAnnotateImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_batch_annotate_images(self, response: image_annotator.BatchAnnotateImagesResponse) -> image_annotator.BatchAnnotateImagesResponse: + """Post-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ImageAnnotatorRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ImageAnnotatorRestInterceptor + + +class ImageAnnotatorRestTransport(ImageAnnotatorTransport): + """REST backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[ + ], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + interceptor: Optional[ImageAnnotatorRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError(f"Unexpected hostname structure: {host}") # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ImageAnnotatorRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1p2beta1") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AsyncBatchAnnotateFiles(ImageAnnotatorRestStub): + def __hash__(self): + return hash("AsyncBatchAnnotateFiles") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.AsyncBatchAnnotateFilesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the async batch annotate + files method over HTTP. + + Args: + request (~.image_annotator.AsyncBatchAnnotateFilesRequest): + The request object. Multiple async file annotation + requests are batched into a single + service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p2beta1/files:asyncBatchAnnotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_async_batch_annotate_files(request, metadata) + pb_request = image_annotator.AsyncBatchAnnotateFilesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_async_batch_annotate_files(resp) + return resp + + class _BatchAnnotateImages(ImageAnnotatorRestStub): + def __hash__(self): + return hash("BatchAnnotateImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.BatchAnnotateImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Call the batch annotate images method over HTTP. + + Args: + request (~.image_annotator.BatchAnnotateImagesRequest): + The request object. Multiple image annotation requests + are batched into a single service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.image_annotator.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p2beta1/images:annotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_annotate_images(request, metadata) + pb_request = image_annotator.BatchAnnotateImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = image_annotator.BatchAnnotateImagesResponse() + pb_resp = image_annotator.BatchAnnotateImagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_annotate_images(resp) + return resp + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AsyncBatchAnnotateFiles(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchAnnotateImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ImageAnnotatorRestTransport', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/__init__.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/__init__.py new file mode 100644 index 00000000..a9e287df --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/__init__.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .geometry import ( + BoundingPoly, + NormalizedVertex, + Position, + Vertex, +) +from .image_annotator import ( + AnnotateFileResponse, + AnnotateImageRequest, + AnnotateImageResponse, + AsyncAnnotateFileRequest, + AsyncAnnotateFileResponse, + AsyncBatchAnnotateFilesRequest, + AsyncBatchAnnotateFilesResponse, + BatchAnnotateImagesRequest, + BatchAnnotateImagesResponse, + ColorInfo, + CropHint, + CropHintsAnnotation, + CropHintsParams, + DominantColorsAnnotation, + EntityAnnotation, + FaceAnnotation, + Feature, + GcsDestination, + GcsSource, + Image, + ImageAnnotationContext, + ImageContext, + ImageProperties, + ImageSource, + InputConfig, + LatLongRect, + LocationInfo, + OperationMetadata, + OutputConfig, + Property, + SafeSearchAnnotation, + TextDetectionParams, + WebDetectionParams, + Likelihood, +) +from .text_annotation import ( + Block, + Page, + Paragraph, + Symbol, + TextAnnotation, + Word, +) +from .web_detection import ( + WebDetection, +) + +__all__ = ( + 'BoundingPoly', + 'NormalizedVertex', + 'Position', + 'Vertex', + 'AnnotateFileResponse', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'GcsDestination', + 'GcsSource', + 'Image', + 'ImageAnnotationContext', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'InputConfig', + 'LatLongRect', + 'LocationInfo', + 'OperationMetadata', + 'OutputConfig', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/geometry.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/geometry.py new file mode 100644 index 00000000..c4bd95e4 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/geometry.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p2beta1', + manifest={ + 'Vertex', + 'NormalizedVertex', + 'BoundingPoly', + 'Position', + }, +) + + +class Vertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the vertex coordinates are in the same scale as the + original image. + + Attributes: + x (int): + X coordinate. + y (int): + Y coordinate. + """ + + x: int = proto.Field( + proto.INT32, + number=1, + ) + y: int = proto.Field( + proto.INT32, + number=2, + ) + + +class NormalizedVertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the normalized vertex coordinates are relative to the + original image and range from 0 to 1. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + + +class BoundingPoly(proto.Message): + r"""A bounding polygon for the detected image annotation. + + Attributes: + vertices (MutableSequence[google.cloud.vision_v1p2beta1.types.Vertex]): + The bounding polygon vertices. + normalized_vertices (MutableSequence[google.cloud.vision_v1p2beta1.types.NormalizedVertex]): + The bounding polygon normalized vertices. + """ + + vertices: MutableSequence['Vertex'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Vertex', + ) + normalized_vertices: MutableSequence['NormalizedVertex'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='NormalizedVertex', + ) + + +class Position(proto.Message): + r"""A 3D position in the image, used primarily for Face detection + landmarks. A valid Position must have both x and y coordinates. + The position coordinates are in the same scale as the original + image. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + z (float): + Z coordinate (or depth). + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + z: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/image_annotator.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/image_annotator.py new file mode 100644 index 00000000..9cb2eaac --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/image_annotator.py @@ -0,0 +1,1406 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p2beta1.types import geometry +from google.cloud.vision_v1p2beta1.types import text_annotation +from google.cloud.vision_v1p2beta1.types import web_detection as gcv_web_detection +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import latlng_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p2beta1', + manifest={ + 'Likelihood', + 'Feature', + 'ImageSource', + 'Image', + 'FaceAnnotation', + 'LocationInfo', + 'Property', + 'EntityAnnotation', + 'SafeSearchAnnotation', + 'LatLongRect', + 'ColorInfo', + 'DominantColorsAnnotation', + 'ImageProperties', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'WebDetectionParams', + 'TextDetectionParams', + 'ImageContext', + 'AnnotateImageRequest', + 'ImageAnnotationContext', + 'AnnotateImageResponse', + 'AnnotateFileResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'InputConfig', + 'OutputConfig', + 'GcsSource', + 'GcsDestination', + 'OperationMetadata', + }, +) + + +class Likelihood(proto.Enum): + r"""A bucketized representation of likelihood, which is intended + to give clients highly stable results across model upgrades. + + Values: + UNKNOWN (0): + Unknown likelihood. + VERY_UNLIKELY (1): + It is very unlikely that the image belongs to + the specified vertical. + UNLIKELY (2): + It is unlikely that the image belongs to the + specified vertical. + POSSIBLE (3): + It is possible that the image belongs to the + specified vertical. + LIKELY (4): + It is likely that the image belongs to the + specified vertical. + VERY_LIKELY (5): + It is very likely that the image belongs to + the specified vertical. + """ + UNKNOWN = 0 + VERY_UNLIKELY = 1 + UNLIKELY = 2 + POSSIBLE = 3 + LIKELY = 4 + VERY_LIKELY = 5 + + +class Feature(proto.Message): + r"""The type of Google Cloud Vision API detection to perform, and the + maximum number of results to return for that type. Multiple + ``Feature`` objects can be specified in the ``features`` list. + + Attributes: + type_ (google.cloud.vision_v1p2beta1.types.Feature.Type): + The feature type. + max_results (int): + Maximum number of results of this type. Does not apply to + ``TEXT_DETECTION``, ``DOCUMENT_TEXT_DETECTION``, or + ``CROP_HINTS``. + model (str): + Model to use for the feature. Supported values: + "builtin/stable" (the default if unset) and + "builtin/latest". ``DOCUMENT_TEXT_DETECTION`` and + ``TEXT_DETECTION`` also support "builtin/weekly" for the + bleeding edge release updated weekly. + """ + class Type(proto.Enum): + r"""Type of Google Cloud Vision API feature to be extracted. + + Values: + TYPE_UNSPECIFIED (0): + Unspecified feature type. + FACE_DETECTION (1): + Run face detection. + LANDMARK_DETECTION (2): + Run landmark detection. + LOGO_DETECTION (3): + Run logo detection. + LABEL_DETECTION (4): + Run label detection. + TEXT_DETECTION (5): + Run text detection / optical character recognition (OCR). + Text detection is optimized for areas of text within a + larger image; if the image is a document, use + ``DOCUMENT_TEXT_DETECTION`` instead. + DOCUMENT_TEXT_DETECTION (11): + Run dense text document OCR. Takes precedence when both + ``DOCUMENT_TEXT_DETECTION`` and ``TEXT_DETECTION`` are + present. + SAFE_SEARCH_DETECTION (6): + Run Safe Search to detect potentially unsafe + or undesirable content. + IMAGE_PROPERTIES (7): + Compute a set of image properties, such as + the image's dominant colors. + CROP_HINTS (9): + Run crop hints. + WEB_DETECTION (10): + Run web detection. + """ + TYPE_UNSPECIFIED = 0 + FACE_DETECTION = 1 + LANDMARK_DETECTION = 2 + LOGO_DETECTION = 3 + LABEL_DETECTION = 4 + TEXT_DETECTION = 5 + DOCUMENT_TEXT_DETECTION = 11 + SAFE_SEARCH_DETECTION = 6 + IMAGE_PROPERTIES = 7 + CROP_HINTS = 9 + WEB_DETECTION = 10 + + type_: Type = proto.Field( + proto.ENUM, + number=1, + enum=Type, + ) + max_results: int = proto.Field( + proto.INT32, + number=2, + ) + model: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ImageSource(proto.Message): + r"""External image source (Google Cloud Storage or web URL image + location). + + Attributes: + gcs_image_uri (str): + **Use ``image_uri`` instead.** + + The Google Cloud Storage URI of the form + ``gs://bucket_name/object_name``. Object versioning is not + supported. See `Google Cloud Storage Request + URIs `__ + for more info. + image_uri (str): + The URI of the source image. Can be either: + + 1. A Google Cloud Storage URI of the form + ``gs://bucket_name/object_name``. Object versioning is + not supported. See `Google Cloud Storage Request + URIs `__ + for more info. + + 2. A publicly-accessible image HTTP/HTTPS URL. When fetching + images from HTTP/HTTPS URLs, Google cannot guarantee that + the request will be completed. Your request may fail if + the specified host denies the request (e.g. due to + request throttling or DOS prevention), or if Google + throttles requests to the site for abuse prevention. You + should not depend on externally-hosted images for + production applications. + + When both ``gcs_image_uri`` and ``image_uri`` are specified, + ``image_uri`` takes precedence. + """ + + gcs_image_uri: str = proto.Field( + proto.STRING, + number=1, + ) + image_uri: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Image(proto.Message): + r"""Client image to perform Google Cloud Vision API tasks over. + + Attributes: + content (bytes): + Image content, represented as a stream of bytes. Note: As + with all ``bytes`` fields, protobuffers use a pure binary + representation, whereas JSON representations use base64. + source (google.cloud.vision_v1p2beta1.types.ImageSource): + Google Cloud Storage image location, or publicly-accessible + image URL. If both ``content`` and ``source`` are provided + for an image, ``content`` takes precedence and is used to + perform the image annotation request. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + source: 'ImageSource' = proto.Field( + proto.MESSAGE, + number=2, + message='ImageSource', + ) + + +class FaceAnnotation(proto.Message): + r"""A face annotation object contains the results of face + detection. + + Attributes: + bounding_poly (google.cloud.vision_v1p2beta1.types.BoundingPoly): + The bounding polygon around the face. The coordinates of the + bounding box are in the original image's scale, as returned + in ``ImageParams``. The bounding box is computed to "frame" + the face in accordance with human expectations. It is based + on the landmarker results. Note that one or more x and/or y + coordinates may not be generated in the ``BoundingPoly`` + (the polygon will be unbounded) if only a partial face + appears in the image to be annotated. + fd_bounding_poly (google.cloud.vision_v1p2beta1.types.BoundingPoly): + The ``fd_bounding_poly`` bounding polygon is tighter than + the ``boundingPoly``, and encloses only the skin part of the + face. Typically, it is used to eliminate the face from any + image analysis that detects the "amount of skin" visible in + an image. It is not based on the landmarker results, only on + the initial face detection, hence the fd (face detection) + prefix. + landmarks (MutableSequence[google.cloud.vision_v1p2beta1.types.FaceAnnotation.Landmark]): + Detected face landmarks. + roll_angle (float): + Roll angle, which indicates the amount of + clockwise/anti-clockwise rotation of the face relative to + the image vertical about the axis perpendicular to the face. + Range [-180,180]. + pan_angle (float): + Yaw angle, which indicates the leftward/rightward angle that + the face is pointing relative to the vertical plane + perpendicular to the image. Range [-180,180]. + tilt_angle (float): + Pitch angle, which indicates the upwards/downwards angle + that the face is pointing relative to the image's horizontal + plane. Range [-180,180]. + detection_confidence (float): + Detection confidence. Range [0, 1]. + landmarking_confidence (float): + Face landmarking confidence. Range [0, 1]. + joy_likelihood (google.cloud.vision_v1p2beta1.types.Likelihood): + Joy likelihood. + sorrow_likelihood (google.cloud.vision_v1p2beta1.types.Likelihood): + Sorrow likelihood. + anger_likelihood (google.cloud.vision_v1p2beta1.types.Likelihood): + Anger likelihood. + surprise_likelihood (google.cloud.vision_v1p2beta1.types.Likelihood): + Surprise likelihood. + under_exposed_likelihood (google.cloud.vision_v1p2beta1.types.Likelihood): + Under-exposed likelihood. + blurred_likelihood (google.cloud.vision_v1p2beta1.types.Likelihood): + Blurred likelihood. + headwear_likelihood (google.cloud.vision_v1p2beta1.types.Likelihood): + Headwear likelihood. + """ + + class Landmark(proto.Message): + r"""A face-specific landmark (for example, a face feature). + + Attributes: + type_ (google.cloud.vision_v1p2beta1.types.FaceAnnotation.Landmark.Type): + Face landmark type. + position (google.cloud.vision_v1p2beta1.types.Position): + Face landmark position. + """ + class Type(proto.Enum): + r"""Face landmark (feature) type. Left and right are defined from the + vantage of the viewer of the image without considering mirror + projections typical of photos. So, ``LEFT_EYE``, typically, is the + person's right eye. + + Values: + UNKNOWN_LANDMARK (0): + Unknown face landmark detected. Should not be + filled. + LEFT_EYE (1): + Left eye. + RIGHT_EYE (2): + Right eye. + LEFT_OF_LEFT_EYEBROW (3): + Left of left eyebrow. + RIGHT_OF_LEFT_EYEBROW (4): + Right of left eyebrow. + LEFT_OF_RIGHT_EYEBROW (5): + Left of right eyebrow. + RIGHT_OF_RIGHT_EYEBROW (6): + Right of right eyebrow. + MIDPOINT_BETWEEN_EYES (7): + Midpoint between eyes. + NOSE_TIP (8): + Nose tip. + UPPER_LIP (9): + Upper lip. + LOWER_LIP (10): + Lower lip. + MOUTH_LEFT (11): + Mouth left. + MOUTH_RIGHT (12): + Mouth right. + MOUTH_CENTER (13): + Mouth center. + NOSE_BOTTOM_RIGHT (14): + Nose, bottom right. + NOSE_BOTTOM_LEFT (15): + Nose, bottom left. + NOSE_BOTTOM_CENTER (16): + Nose, bottom center. + LEFT_EYE_TOP_BOUNDARY (17): + Left eye, top boundary. + LEFT_EYE_RIGHT_CORNER (18): + Left eye, right corner. + LEFT_EYE_BOTTOM_BOUNDARY (19): + Left eye, bottom boundary. + LEFT_EYE_LEFT_CORNER (20): + Left eye, left corner. + RIGHT_EYE_TOP_BOUNDARY (21): + Right eye, top boundary. + RIGHT_EYE_RIGHT_CORNER (22): + Right eye, right corner. + RIGHT_EYE_BOTTOM_BOUNDARY (23): + Right eye, bottom boundary. + RIGHT_EYE_LEFT_CORNER (24): + Right eye, left corner. + LEFT_EYEBROW_UPPER_MIDPOINT (25): + Left eyebrow, upper midpoint. + RIGHT_EYEBROW_UPPER_MIDPOINT (26): + Right eyebrow, upper midpoint. + LEFT_EAR_TRAGION (27): + Left ear tragion. + RIGHT_EAR_TRAGION (28): + Right ear tragion. + LEFT_EYE_PUPIL (29): + Left eye pupil. + RIGHT_EYE_PUPIL (30): + Right eye pupil. + FOREHEAD_GLABELLA (31): + Forehead glabella. + CHIN_GNATHION (32): + Chin gnathion. + CHIN_LEFT_GONION (33): + Chin left gonion. + CHIN_RIGHT_GONION (34): + Chin right gonion. + """ + UNKNOWN_LANDMARK = 0 + LEFT_EYE = 1 + RIGHT_EYE = 2 + LEFT_OF_LEFT_EYEBROW = 3 + RIGHT_OF_LEFT_EYEBROW = 4 + LEFT_OF_RIGHT_EYEBROW = 5 + RIGHT_OF_RIGHT_EYEBROW = 6 + MIDPOINT_BETWEEN_EYES = 7 + NOSE_TIP = 8 + UPPER_LIP = 9 + LOWER_LIP = 10 + MOUTH_LEFT = 11 + MOUTH_RIGHT = 12 + MOUTH_CENTER = 13 + NOSE_BOTTOM_RIGHT = 14 + NOSE_BOTTOM_LEFT = 15 + NOSE_BOTTOM_CENTER = 16 + LEFT_EYE_TOP_BOUNDARY = 17 + LEFT_EYE_RIGHT_CORNER = 18 + LEFT_EYE_BOTTOM_BOUNDARY = 19 + LEFT_EYE_LEFT_CORNER = 20 + RIGHT_EYE_TOP_BOUNDARY = 21 + RIGHT_EYE_RIGHT_CORNER = 22 + RIGHT_EYE_BOTTOM_BOUNDARY = 23 + RIGHT_EYE_LEFT_CORNER = 24 + LEFT_EYEBROW_UPPER_MIDPOINT = 25 + RIGHT_EYEBROW_UPPER_MIDPOINT = 26 + LEFT_EAR_TRAGION = 27 + RIGHT_EAR_TRAGION = 28 + LEFT_EYE_PUPIL = 29 + RIGHT_EYE_PUPIL = 30 + FOREHEAD_GLABELLA = 31 + CHIN_GNATHION = 32 + CHIN_LEFT_GONION = 33 + CHIN_RIGHT_GONION = 34 + + type_: 'FaceAnnotation.Landmark.Type' = proto.Field( + proto.ENUM, + number=3, + enum='FaceAnnotation.Landmark.Type', + ) + position: geometry.Position = proto.Field( + proto.MESSAGE, + number=4, + message=geometry.Position, + ) + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + fd_bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + landmarks: MutableSequence[Landmark] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=Landmark, + ) + roll_angle: float = proto.Field( + proto.FLOAT, + number=4, + ) + pan_angle: float = proto.Field( + proto.FLOAT, + number=5, + ) + tilt_angle: float = proto.Field( + proto.FLOAT, + number=6, + ) + detection_confidence: float = proto.Field( + proto.FLOAT, + number=7, + ) + landmarking_confidence: float = proto.Field( + proto.FLOAT, + number=8, + ) + joy_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + sorrow_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=10, + enum='Likelihood', + ) + anger_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=11, + enum='Likelihood', + ) + surprise_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=12, + enum='Likelihood', + ) + under_exposed_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=13, + enum='Likelihood', + ) + blurred_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=14, + enum='Likelihood', + ) + headwear_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=15, + enum='Likelihood', + ) + + +class LocationInfo(proto.Message): + r"""Detected entity location information. + + Attributes: + lat_lng (google.type.latlng_pb2.LatLng): + lat/long location coordinates. + """ + + lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + + +class Property(proto.Message): + r"""A ``Property`` consists of a user-supplied name/value pair. + + Attributes: + name (str): + Name of the property. + value (str): + Value of the property. + uint64_value (int): + Value of numeric properties. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + uint64_value: int = proto.Field( + proto.UINT64, + number=3, + ) + + +class EntityAnnotation(proto.Message): + r"""Set of detected entity features. + + Attributes: + mid (str): + Opaque entity ID. Some IDs may be available in `Google + Knowledge Graph Search + API `__. + locale (str): + The language code for the locale in which the entity textual + ``description`` is expressed. + description (str): + Entity textual description, expressed in its ``locale`` + language. + score (float): + Overall score of the result. Range [0, 1]. + confidence (float): + **Deprecated. Use ``score`` instead.** The accuracy of the + entity detection in an image. For example, for an image in + which the "Eiffel Tower" entity is detected, this field + represents the confidence that there is a tower in the query + image. Range [0, 1]. + topicality (float): + The relevancy of the ICA (Image Content Annotation) label to + the image. For example, the relevancy of "tower" is likely + higher to an image containing the detected "Eiffel Tower" + than to an image containing a detected distant towering + building, even though the confidence that there is a tower + in each image may be the same. Range [0, 1]. + bounding_poly (google.cloud.vision_v1p2beta1.types.BoundingPoly): + Image region to which this entity belongs. Not produced for + ``LABEL_DETECTION`` features. + locations (MutableSequence[google.cloud.vision_v1p2beta1.types.LocationInfo]): + The location information for the detected entity. Multiple + ``LocationInfo`` elements can be present because one + location may indicate the location of the scene in the + image, and another location may indicate the location of the + place where the image was taken. Location information is + usually present for landmarks. + properties (MutableSequence[google.cloud.vision_v1p2beta1.types.Property]): + Some entities may have optional user-supplied ``Property`` + (name/value) fields, such a score or string that qualifies + the entity. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + locale: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + topicality: float = proto.Field( + proto.FLOAT, + number=6, + ) + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=7, + message=geometry.BoundingPoly, + ) + locations: MutableSequence['LocationInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message='LocationInfo', + ) + properties: MutableSequence['Property'] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message='Property', + ) + + +class SafeSearchAnnotation(proto.Message): + r"""Set of features pertaining to the image, computed by computer + vision methods over safe-search verticals (for example, adult, + spoof, medical, violence). + + Attributes: + adult (google.cloud.vision_v1p2beta1.types.Likelihood): + Represents the adult content likelihood for + the image. Adult content may contain elements + such as nudity, pornographic images or cartoons, + or sexual activities. + spoof (google.cloud.vision_v1p2beta1.types.Likelihood): + Spoof likelihood. The likelihood that an + modification was made to the image's canonical + version to make it appear funny or offensive. + medical (google.cloud.vision_v1p2beta1.types.Likelihood): + Likelihood that this is a medical image. + violence (google.cloud.vision_v1p2beta1.types.Likelihood): + Likelihood that this image contains violent + content. + racy (google.cloud.vision_v1p2beta1.types.Likelihood): + Likelihood that the request image contains + racy content. Racy content may include (but is + not limited to) skimpy or sheer clothing, + strategically covered nudity, lewd or + provocative poses, or close-ups of sensitive + body areas. + """ + + adult: 'Likelihood' = proto.Field( + proto.ENUM, + number=1, + enum='Likelihood', + ) + spoof: 'Likelihood' = proto.Field( + proto.ENUM, + number=2, + enum='Likelihood', + ) + medical: 'Likelihood' = proto.Field( + proto.ENUM, + number=3, + enum='Likelihood', + ) + violence: 'Likelihood' = proto.Field( + proto.ENUM, + number=4, + enum='Likelihood', + ) + racy: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + + +class LatLongRect(proto.Message): + r"""Rectangle determined by min and max ``LatLng`` pairs. + + Attributes: + min_lat_lng (google.type.latlng_pb2.LatLng): + Min lat/long pair. + max_lat_lng (google.type.latlng_pb2.LatLng): + Max lat/long pair. + """ + + min_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + max_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=2, + message=latlng_pb2.LatLng, + ) + + +class ColorInfo(proto.Message): + r"""Color information consists of RGB channels, score, and the + fraction of the image that the color occupies in the image. + + Attributes: + color (google.type.color_pb2.Color): + RGB components of the color. + score (float): + Image-specific score for this color. Value in range [0, 1]. + pixel_fraction (float): + The fraction of pixels the color occupies in the image. + Value in range [0, 1]. + """ + + color: color_pb2.Color = proto.Field( + proto.MESSAGE, + number=1, + message=color_pb2.Color, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + pixel_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class DominantColorsAnnotation(proto.Message): + r"""Set of dominant colors and their corresponding scores. + + Attributes: + colors (MutableSequence[google.cloud.vision_v1p2beta1.types.ColorInfo]): + RGB color values with their score and pixel + fraction. + """ + + colors: MutableSequence['ColorInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ColorInfo', + ) + + +class ImageProperties(proto.Message): + r"""Stores image properties, such as dominant colors. + + Attributes: + dominant_colors (google.cloud.vision_v1p2beta1.types.DominantColorsAnnotation): + If present, dominant colors completed + successfully. + """ + + dominant_colors: 'DominantColorsAnnotation' = proto.Field( + proto.MESSAGE, + number=1, + message='DominantColorsAnnotation', + ) + + +class CropHint(proto.Message): + r"""Single crop hint that is used to generate a new crop when + serving an image. + + Attributes: + bounding_poly (google.cloud.vision_v1p2beta1.types.BoundingPoly): + The bounding polygon for the crop region. The coordinates of + the bounding box are in the original image's scale, as + returned in ``ImageParams``. + confidence (float): + Confidence of this being a salient region. Range [0, 1]. + importance_fraction (float): + Fraction of importance of this salient region + with respect to the original image. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + importance_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class CropHintsAnnotation(proto.Message): + r"""Set of crop hints that are used to generate new crops when + serving images. + + Attributes: + crop_hints (MutableSequence[google.cloud.vision_v1p2beta1.types.CropHint]): + Crop hint results. + """ + + crop_hints: MutableSequence['CropHint'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='CropHint', + ) + + +class CropHintsParams(proto.Message): + r"""Parameters for crop hints annotation request. + + Attributes: + aspect_ratios (MutableSequence[float]): + Aspect ratios in floats, representing the + ratio of the width to the height of the image. + For example, if the desired aspect ratio is 4/3, + the corresponding float value should be 1.33333. + If not specified, the best possible crop is + returned. The number of provided aspect ratios + is limited to a maximum of 16; any aspect ratios + provided after the 16th are ignored. + """ + + aspect_ratios: MutableSequence[float] = proto.RepeatedField( + proto.FLOAT, + number=1, + ) + + +class WebDetectionParams(proto.Message): + r"""Parameters for web detection request. + + Attributes: + include_geo_results (bool): + Whether to include results derived from the + geo information in the image. + """ + + include_geo_results: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class TextDetectionParams(proto.Message): + r"""Parameters for text detections. This is used to control + TEXT_DETECTION and DOCUMENT_TEXT_DETECTION features. + + Attributes: + enable_text_detection_confidence_score (bool): + By default, Cloud Vision API only includes confidence score + for DOCUMENT_TEXT_DETECTION result. Set the flag to true to + include confidence score for TEXT_DETECTION as well. + advanced_ocr_options (MutableSequence[str]): + A list of advanced OCR options to fine-tune + OCR behavior. + """ + + enable_text_detection_confidence_score: bool = proto.Field( + proto.BOOL, + number=9, + ) + advanced_ocr_options: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + + +class ImageContext(proto.Message): + r"""Image context and/or feature-specific parameters. + + Attributes: + lat_long_rect (google.cloud.vision_v1p2beta1.types.LatLongRect): + Not used. + language_hints (MutableSequence[str]): + List of languages to use for TEXT_DETECTION. In most cases, + an empty value yields the best results since it enables + automatic language detection. For languages based on the + Latin alphabet, setting ``language_hints`` is not needed. In + rare cases, when the language of the text in the image is + known, setting a hint will help get better results (although + it will be a significant hindrance if the hint is wrong). + Text detection returns an error if one or more of the + specified languages is not one of the `supported + languages `__. + crop_hints_params (google.cloud.vision_v1p2beta1.types.CropHintsParams): + Parameters for crop hints annotation request. + web_detection_params (google.cloud.vision_v1p2beta1.types.WebDetectionParams): + Parameters for web detection. + text_detection_params (google.cloud.vision_v1p2beta1.types.TextDetectionParams): + Parameters for text detection and document + text detection. + """ + + lat_long_rect: 'LatLongRect' = proto.Field( + proto.MESSAGE, + number=1, + message='LatLongRect', + ) + language_hints: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + crop_hints_params: 'CropHintsParams' = proto.Field( + proto.MESSAGE, + number=4, + message='CropHintsParams', + ) + web_detection_params: 'WebDetectionParams' = proto.Field( + proto.MESSAGE, + number=6, + message='WebDetectionParams', + ) + text_detection_params: 'TextDetectionParams' = proto.Field( + proto.MESSAGE, + number=12, + message='TextDetectionParams', + ) + + +class AnnotateImageRequest(proto.Message): + r"""Request for performing Google Cloud Vision API tasks over a + user-provided image, with user-requested features. + + Attributes: + image (google.cloud.vision_v1p2beta1.types.Image): + The image to be processed. + features (MutableSequence[google.cloud.vision_v1p2beta1.types.Feature]): + Requested features. + image_context (google.cloud.vision_v1p2beta1.types.ImageContext): + Additional context that may accompany the + image. + """ + + image: 'Image' = proto.Field( + proto.MESSAGE, + number=1, + message='Image', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + + +class ImageAnnotationContext(proto.Message): + r"""If an image was produced from a file (e.g. a PDF), this + message gives information about the source of that image. + + Attributes: + uri (str): + The URI of the file used to produce the + image. + page_number (int): + If the file was a PDF or TIFF, this field + gives the page number within the file used to + produce the image. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + page_number: int = proto.Field( + proto.INT32, + number=2, + ) + + +class AnnotateImageResponse(proto.Message): + r"""Response to an image annotation request. + + Attributes: + face_annotations (MutableSequence[google.cloud.vision_v1p2beta1.types.FaceAnnotation]): + If present, face detection has completed + successfully. + landmark_annotations (MutableSequence[google.cloud.vision_v1p2beta1.types.EntityAnnotation]): + If present, landmark detection has completed + successfully. + logo_annotations (MutableSequence[google.cloud.vision_v1p2beta1.types.EntityAnnotation]): + If present, logo detection has completed + successfully. + label_annotations (MutableSequence[google.cloud.vision_v1p2beta1.types.EntityAnnotation]): + If present, label detection has completed + successfully. + text_annotations (MutableSequence[google.cloud.vision_v1p2beta1.types.EntityAnnotation]): + If present, text (OCR) detection has + completed successfully. + full_text_annotation (google.cloud.vision_v1p2beta1.types.TextAnnotation): + If present, text (OCR) detection or document + (OCR) text detection has completed successfully. + This annotation provides the structural + hierarchy for the OCR detected text. + safe_search_annotation (google.cloud.vision_v1p2beta1.types.SafeSearchAnnotation): + If present, safe-search annotation has + completed successfully. + image_properties_annotation (google.cloud.vision_v1p2beta1.types.ImageProperties): + If present, image properties were extracted + successfully. + crop_hints_annotation (google.cloud.vision_v1p2beta1.types.CropHintsAnnotation): + If present, crop hints have completed + successfully. + web_detection (google.cloud.vision_v1p2beta1.types.WebDetection): + If present, web detection has completed + successfully. + error (google.rpc.status_pb2.Status): + If set, represents the error message for the operation. Note + that filled-in image annotations are guaranteed to be + correct, even when ``error`` is set. + context (google.cloud.vision_v1p2beta1.types.ImageAnnotationContext): + If present, contextual information is needed + to understand where this image comes from. + """ + + face_annotations: MutableSequence['FaceAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='FaceAnnotation', + ) + landmark_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='EntityAnnotation', + ) + logo_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='EntityAnnotation', + ) + label_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='EntityAnnotation', + ) + text_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='EntityAnnotation', + ) + full_text_annotation: text_annotation.TextAnnotation = proto.Field( + proto.MESSAGE, + number=12, + message=text_annotation.TextAnnotation, + ) + safe_search_annotation: 'SafeSearchAnnotation' = proto.Field( + proto.MESSAGE, + number=6, + message='SafeSearchAnnotation', + ) + image_properties_annotation: 'ImageProperties' = proto.Field( + proto.MESSAGE, + number=8, + message='ImageProperties', + ) + crop_hints_annotation: 'CropHintsAnnotation' = proto.Field( + proto.MESSAGE, + number=11, + message='CropHintsAnnotation', + ) + web_detection: gcv_web_detection.WebDetection = proto.Field( + proto.MESSAGE, + number=13, + message=gcv_web_detection.WebDetection, + ) + error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=9, + message=status_pb2.Status, + ) + context: 'ImageAnnotationContext' = proto.Field( + proto.MESSAGE, + number=21, + message='ImageAnnotationContext', + ) + + +class AnnotateFileResponse(proto.Message): + r"""Response to a single file annotation request. A file may + contain one or more images, which individually have their own + responses. + + Attributes: + input_config (google.cloud.vision_v1p2beta1.types.InputConfig): + Information about the file for which this + response is generated. + responses (MutableSequence[google.cloud.vision_v1p2beta1.types.AnnotateImageResponse]): + Individual responses to images found within + the file. + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='AnnotateImageResponse', + ) + + +class BatchAnnotateImagesRequest(proto.Message): + r"""Multiple image annotation requests are batched into a single + service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p2beta1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + """ + + requests: MutableSequence['AnnotateImageRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageRequest', + ) + + +class BatchAnnotateImagesResponse(proto.Message): + r"""Response to a batch image annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1p2beta1.types.AnnotateImageResponse]): + Individual responses to image annotation + requests within the batch. + """ + + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageResponse', + ) + + +class AsyncAnnotateFileRequest(proto.Message): + r"""An offline file annotation request. + + Attributes: + input_config (google.cloud.vision_v1p2beta1.types.InputConfig): + Required. Information about the input file. + features (MutableSequence[google.cloud.vision_v1p2beta1.types.Feature]): + Required. Requested features. + image_context (google.cloud.vision_v1p2beta1.types.ImageContext): + Additional context that may accompany the + image(s) in the file. + output_config (google.cloud.vision_v1p2beta1.types.OutputConfig): + Required. The desired output location and + metadata (e.g. format). + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=4, + message='OutputConfig', + ) + + +class AsyncAnnotateFileResponse(proto.Message): + r"""The response for a single offline file annotation request. + + Attributes: + output_config (google.cloud.vision_v1p2beta1.types.OutputConfig): + The output location and metadata from + AsyncAnnotateFileRequest. + """ + + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='OutputConfig', + ) + + +class AsyncBatchAnnotateFilesRequest(proto.Message): + r"""Multiple async file annotation requests are batched into a + single service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p2beta1.types.AsyncAnnotateFileRequest]): + Required. Individual async file annotation + requests for this batch. + """ + + requests: MutableSequence['AsyncAnnotateFileRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AsyncAnnotateFileRequest', + ) + + +class AsyncBatchAnnotateFilesResponse(proto.Message): + r"""Response to an async batch file annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1p2beta1.types.AsyncAnnotateFileResponse]): + The list of file annotation responses, one + for each request in + AsyncBatchAnnotateFilesRequest. + """ + + responses: MutableSequence['AsyncAnnotateFileResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AsyncAnnotateFileResponse', + ) + + +class InputConfig(proto.Message): + r"""The desired input location and metadata. + + Attributes: + gcs_source (google.cloud.vision_v1p2beta1.types.GcsSource): + The Google Cloud Storage location to read the + input from. + mime_type (str): + The type of the file. Currently only + "application/pdf" and "image/tiff" are + supported. Wildcards are not supported. + """ + + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=1, + message='GcsSource', + ) + mime_type: str = proto.Field( + proto.STRING, + number=2, + ) + + +class OutputConfig(proto.Message): + r"""The desired output location and metadata. + + Attributes: + gcs_destination (google.cloud.vision_v1p2beta1.types.GcsDestination): + The Google Cloud Storage location to write + the output(s) to. + batch_size (int): + The max number of response protos to put into each output + JSON file on GCS. The valid range is [1, 100]. If not + specified, the default value is 20. + + For example, for one pdf file with 100 pages, 100 response + protos will be generated. If ``batch_size`` = 20, then 5 + json files each containing 20 response protos will be + written under the prefix ``gcs_destination``.\ ``uri``. + + Currently, batch_size only applies to GcsDestination, with + potential future support for other output configurations. + """ + + gcs_destination: 'GcsDestination' = proto.Field( + proto.MESSAGE, + number=1, + message='GcsDestination', + ) + batch_size: int = proto.Field( + proto.INT32, + number=2, + ) + + +class GcsSource(proto.Message): + r"""The Google Cloud Storage location where the input will be + read from. + + Attributes: + uri (str): + Google Cloud Storage URI for the input file. + This must only be a GCS object. Wildcards are + not currently supported. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GcsDestination(proto.Message): + r"""The Google Cloud Storage location where the output will be + written to. + + Attributes: + uri (str): + Google Cloud Storage URI where the results will be stored. + Results will be in JSON format and preceded by its + corresponding input URI. This field can either represent a + single file, or a prefix for multiple outputs. Prefixes must + end in a ``/``. + + Examples: + + - File: gs://bucket-name/filename.json + - Prefix: gs://bucket-name/prefix/here/ + - File: gs://bucket-name/prefix/here + + If multiple outputs, each response is still + AnnotateFileResponse, each of which contains some subset of + the full list of AnnotateImageResponse. Multiple outputs can + happen if, for example, the output JSON is too large and + overflows into multiple sharded files. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class OperationMetadata(proto.Message): + r"""Contains metadata for the BatchAnnotateImages operation. + + Attributes: + state (google.cloud.vision_v1p2beta1.types.OperationMetadata.State): + Current state of the batch operation. + create_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request was received. + update_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the operation result was last + updated. + """ + class State(proto.Enum): + r"""Batch operation states. + + Values: + STATE_UNSPECIFIED (0): + Invalid. + CREATED (1): + Request is received. + RUNNING (2): + Request is actively being processed. + DONE (3): + The batch processing is done. + CANCELLED (4): + The batch processing was cancelled. + """ + STATE_UNSPECIFIED = 0 + CREATED = 1 + RUNNING = 2 + DONE = 3 + CANCELLED = 4 + + state: State = proto.Field( + proto.ENUM, + number=1, + enum=State, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/text_annotation.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/text_annotation.py new file mode 100644 index 00000000..fbb9b395 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/text_annotation.py @@ -0,0 +1,429 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p2beta1.types import geometry + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p2beta1', + manifest={ + 'TextAnnotation', + 'Page', + 'Block', + 'Paragraph', + 'Word', + 'Symbol', + }, +) + + +class TextAnnotation(proto.Message): + r"""TextAnnotation contains a structured representation of OCR extracted + text. The hierarchy of an OCR extracted text structure is like this: + TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol Each + structural component, starting from Page, may further have their own + properties. Properties describe detected languages, breaks etc.. + Please refer to the + [TextAnnotation.TextProperty][google.cloud.vision.v1p2beta1.TextAnnotation.TextProperty] + message definition below for more detail. + + Attributes: + pages (MutableSequence[google.cloud.vision_v1p2beta1.types.Page]): + List of pages detected by OCR. + text (str): + UTF-8 text detected on the pages. + """ + + class DetectedLanguage(proto.Message): + r"""Detected language for a structural component. + + Attributes: + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + confidence (float): + Confidence of detected language. Range [0, 1]. + """ + + language_code: str = proto.Field( + proto.STRING, + number=1, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class DetectedBreak(proto.Message): + r"""Detected start or end of a structural component. + + Attributes: + type_ (google.cloud.vision_v1p2beta1.types.TextAnnotation.DetectedBreak.BreakType): + Detected break type. + is_prefix (bool): + True if break prepends the element. + """ + class BreakType(proto.Enum): + r"""Enum to denote the type of break found. New line, space etc. + + Values: + UNKNOWN (0): + Unknown break label type. + SPACE (1): + Regular space. + SURE_SPACE (2): + Sure space (very wide). + EOL_SURE_SPACE (3): + Line-wrapping break. + HYPHEN (4): + End-line hyphen that is not present in text; does not + co-occur with ``SPACE``, ``LEADER_SPACE``, or + ``LINE_BREAK``. + LINE_BREAK (5): + Line break that ends a paragraph. + """ + UNKNOWN = 0 + SPACE = 1 + SURE_SPACE = 2 + EOL_SURE_SPACE = 3 + HYPHEN = 4 + LINE_BREAK = 5 + + type_: 'TextAnnotation.DetectedBreak.BreakType' = proto.Field( + proto.ENUM, + number=1, + enum='TextAnnotation.DetectedBreak.BreakType', + ) + is_prefix: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class TextProperty(proto.Message): + r"""Additional information detected on the structural component. + + Attributes: + detected_languages (MutableSequence[google.cloud.vision_v1p2beta1.types.TextAnnotation.DetectedLanguage]): + A list of detected languages together with + confidence. + detected_break (google.cloud.vision_v1p2beta1.types.TextAnnotation.DetectedBreak): + Detected start or end of a text segment. + """ + + detected_languages: MutableSequence['TextAnnotation.DetectedLanguage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='TextAnnotation.DetectedLanguage', + ) + detected_break: 'TextAnnotation.DetectedBreak' = proto.Field( + proto.MESSAGE, + number=2, + message='TextAnnotation.DetectedBreak', + ) + + pages: MutableSequence['Page'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Page', + ) + text: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Page(proto.Message): + r"""Detected page from OCR. + + Attributes: + property (google.cloud.vision_v1p2beta1.types.TextAnnotation.TextProperty): + Additional information detected on the page. + width (int): + Page width. For PDFs the unit is points. For + images (including TIFFs) the unit is pixels. + height (int): + Page height. For PDFs the unit is points. For + images (including TIFFs) the unit is pixels. + blocks (MutableSequence[google.cloud.vision_v1p2beta1.types.Block]): + List of blocks of text, images etc on this + page. + confidence (float): + Confidence of the OCR results on the page. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + width: int = proto.Field( + proto.INT32, + number=2, + ) + height: int = proto.Field( + proto.INT32, + number=3, + ) + blocks: MutableSequence['Block'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='Block', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Block(proto.Message): + r"""Logical element on the page. + + Attributes: + property (google.cloud.vision_v1p2beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + block. + bounding_box (google.cloud.vision_v1p2beta1.types.BoundingPoly): + The bounding box for the block. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: + + :: + + 0----1 + | | + 3----2 + + - when it's rotated 180 degrees around the top-left corner + it becomes: + + :: + + 2----3 + | | + 1----0 + + and the vertice order will still be (0, 1, 2, 3). + paragraphs (MutableSequence[google.cloud.vision_v1p2beta1.types.Paragraph]): + List of paragraphs in this block (if this + blocks is of type text). + block_type (google.cloud.vision_v1p2beta1.types.Block.BlockType): + Detected block type (text, image etc) for + this block. + confidence (float): + Confidence of the OCR results on the block. Range [0, 1]. + """ + class BlockType(proto.Enum): + r"""Type of a block (text, image etc) as identified by OCR. + + Values: + UNKNOWN (0): + Unknown block type. + TEXT (1): + Regular text block. + TABLE (2): + Table block. + PICTURE (3): + Image block. + RULER (4): + Horizontal/vertical line box. + BARCODE (5): + Barcode block. + """ + UNKNOWN = 0 + TEXT = 1 + TABLE = 2 + PICTURE = 3 + RULER = 4 + BARCODE = 5 + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + paragraphs: MutableSequence['Paragraph'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Paragraph', + ) + block_type: BlockType = proto.Field( + proto.ENUM, + number=4, + enum=BlockType, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Paragraph(proto.Message): + r"""Structural unit of text representing a number of words in + certain order. + + Attributes: + property (google.cloud.vision_v1p2beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + paragraph. + bounding_box (google.cloud.vision_v1p2beta1.types.BoundingPoly): + The bounding box for the paragraph. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + words (MutableSequence[google.cloud.vision_v1p2beta1.types.Word]): + List of words in this paragraph. + confidence (float): + Confidence of the OCR results for the paragraph. Range [0, + 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + words: MutableSequence['Word'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Word', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Word(proto.Message): + r"""A word representation. + + Attributes: + property (google.cloud.vision_v1p2beta1.types.TextAnnotation.TextProperty): + Additional information detected for the word. + bounding_box (google.cloud.vision_v1p2beta1.types.BoundingPoly): + The bounding box for the word. The vertices are in the order + of top-left, top-right, bottom-right, bottom-left. When a + rotation of the bounding box is detected the rotation is + represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + symbols (MutableSequence[google.cloud.vision_v1p2beta1.types.Symbol]): + List of symbols in the word. + The order of the symbols follows the natural + reading order. + confidence (float): + Confidence of the OCR results for the word. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + symbols: MutableSequence['Symbol'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Symbol', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Symbol(proto.Message): + r"""A single symbol representation. + + Attributes: + property (google.cloud.vision_v1p2beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + symbol. + bounding_box (google.cloud.vision_v1p2beta1.types.BoundingPoly): + The bounding box for the symbol. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + text (str): + The actual UTF-8 representation of the + symbol. + confidence (float): + Confidence of the OCR results for the symbol. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + text: str = proto.Field( + proto.STRING, + number=3, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/web_detection.py b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/web_detection.py new file mode 100644 index 00000000..215e12d7 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/google/cloud/vision_v1p2beta1/types/web_detection.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p2beta1', + manifest={ + 'WebDetection', + }, +) + + +class WebDetection(proto.Message): + r"""Relevant information for the image from the Internet. + + Attributes: + web_entities (MutableSequence[google.cloud.vision_v1p2beta1.types.WebDetection.WebEntity]): + Deduced entities from similar images on the + Internet. + full_matching_images (MutableSequence[google.cloud.vision_v1p2beta1.types.WebDetection.WebImage]): + Fully matching images from the Internet. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1p2beta1.types.WebDetection.WebImage]): + Partial matching images from the Internet. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + pages_with_matching_images (MutableSequence[google.cloud.vision_v1p2beta1.types.WebDetection.WebPage]): + Web pages containing the matching images from + the Internet. + visually_similar_images (MutableSequence[google.cloud.vision_v1p2beta1.types.WebDetection.WebImage]): + The visually similar image results. + best_guess_labels (MutableSequence[google.cloud.vision_v1p2beta1.types.WebDetection.WebLabel]): + Best guess text labels for the request image. + """ + + class WebEntity(proto.Message): + r"""Entity deduced from similar images on the Internet. + + Attributes: + entity_id (str): + Opaque entity ID. + score (float): + Overall relevancy score for the entity. + Not normalized and not comparable across + different image queries. + description (str): + Canonical description of the entity, in + English. + """ + + entity_id: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + + class WebImage(proto.Message): + r"""Metadata for online images. + + Attributes: + url (str): + The result image URL. + score (float): + (Deprecated) Overall relevancy score for the + image. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class WebPage(proto.Message): + r"""Metadata for web pages. + + Attributes: + url (str): + The result web page URL. + score (float): + (Deprecated) Overall relevancy score for the + web page. + page_title (str): + Title for the web page, may contain HTML + markups. + full_matching_images (MutableSequence[google.cloud.vision_v1p2beta1.types.WebDetection.WebImage]): + Fully matching images on the page. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1p2beta1.types.WebDetection.WebImage]): + Partial matching images on the page. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + page_title: str = proto.Field( + proto.STRING, + number=3, + ) + full_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='WebDetection.WebImage', + ) + partial_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='WebDetection.WebImage', + ) + + class WebLabel(proto.Message): + r"""Label to provide extra metadata for the web detection. + + Attributes: + label (str): + Label for extra metadata. + language_code (str): + The BCP-47 language code for ``label``, such as "en-US" or + "sr-Latn". For more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + """ + + label: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + + web_entities: MutableSequence[WebEntity] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=WebEntity, + ) + full_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=WebImage, + ) + partial_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=WebImage, + ) + pages_with_matching_images: MutableSequence[WebPage] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=WebPage, + ) + visually_similar_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=WebImage, + ) + best_guess_labels: MutableSequence[WebLabel] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=WebLabel, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p2beta1/mypy.ini b/owl-bot-staging/v1p2beta1/mypy.ini new file mode 100644 index 00000000..574c5aed --- /dev/null +++ b/owl-bot-staging/v1p2beta1/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/v1p2beta1/noxfile.py b/owl-bot-staging/v1p2beta1/noxfile.py new file mode 100644 index 00000000..a958b791 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/noxfile.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +import pathlib +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = subprocess.check_output([sys.executable, "setup.py", "--name"], encoding="utf-8") + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.11" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "lint_setup_py", +] + +@nox.session(python=ALL_PYTHON) +def unit(session): + """Run the unit test suite.""" + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.') + + session.run( + 'py.test', + '--quiet', + '--cov=google/cloud/vision_v1p2beta1/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)) + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + session.install( + 'mypy', + 'types-requests', + 'types-protobuf' + ) + session.install('.') + session.run( + 'mypy', + '--explicit-package-bases', + 'google', + ) + + +@nox.session +def update_lower_bounds(session): + """Update lower bounds in constraints.txt to match setup.py""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'update', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + + +@nox.session +def check_lower_bounds(session): + """Check lower bounds in setup.py are reflected in constraints file""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'check', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install("sphinx==7.0.1", "alabaster", "recommonmark") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", BLACK_VERSION) + session.run( + "black", + "--check", + *BLACK_PATHS, + ) + session.run("flake8", "google", "tests", "samples") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *BLACK_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") diff --git a/owl-bot-staging/v1p2beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json b/owl-bot-staging/v1p2beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json new file mode 100644 index 00000000..52e22f36 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p2beta1.json @@ -0,0 +1,337 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.vision.v1p2beta1", + "version": "v1p2beta1" + } + ], + "language": "PYTHON", + "name": "google-cloud-vision", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p2beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p2beta1.ImageAnnotatorAsyncClient.async_batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1p2beta1.ImageAnnotator.AsyncBatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1p2beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p2beta1.types.AsyncBatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p2beta1.types.AsyncAnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "async_batch_annotate_files" + }, + "description": "Sample for AsyncBatchAnnotateFiles", + "file": "vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p2beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p2beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p2beta1.ImageAnnotatorClient.async_batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1p2beta1.ImageAnnotator.AsyncBatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1p2beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p2beta1.types.AsyncBatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p2beta1.types.AsyncAnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "async_batch_annotate_files" + }, + "description": "Sample for AsyncBatchAnnotateFiles", + "file": "vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p2beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p2beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p2beta1.ImageAnnotatorAsyncClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p2beta1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p2beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p2beta1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p2beta1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p2beta1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1p2beta1_generated_image_annotator_batch_annotate_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p2beta1_generated_ImageAnnotator_BatchAnnotateImages_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p2beta1_generated_image_annotator_batch_annotate_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p2beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p2beta1.ImageAnnotatorClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p2beta1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p2beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p2beta1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p2beta1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p2beta1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1p2beta1_generated_image_annotator_batch_annotate_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p2beta1_generated_ImageAnnotator_BatchAnnotateImages_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p2beta1_generated_image_annotator_batch_annotate_images_sync.py" + } + ] +} diff --git a/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_async.py b/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_async.py new file mode 100644 index 00000000..78cdd23d --- /dev/null +++ b/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p2beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p2beta1 + + +async def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p2beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p2beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1p2beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async] diff --git a/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_sync.py b/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_sync.py new file mode 100644 index 00000000..2f40d1fd --- /dev/null +++ b/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_async_batch_annotate_files_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p2beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p2beta1 + + +def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p2beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p2beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1p2beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync] diff --git a/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_batch_annotate_images_async.py b/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_batch_annotate_images_async.py new file mode 100644 index 00000000..25e42384 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_batch_annotate_images_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p2beta1_generated_ImageAnnotator_BatchAnnotateImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p2beta1 + + +async def sample_batch_annotate_images(): + # Create a client + client = vision_v1p2beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p2beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1p2beta1_generated_ImageAnnotator_BatchAnnotateImages_async] diff --git a/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_batch_annotate_images_sync.py b/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_batch_annotate_images_sync.py new file mode 100644 index 00000000..1abd4619 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/samples/generated_samples/vision_v1p2beta1_generated_image_annotator_batch_annotate_images_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p2beta1_generated_ImageAnnotator_BatchAnnotateImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p2beta1 + + +def sample_batch_annotate_images(): + # Create a client + client = vision_v1p2beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p2beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1p2beta1_generated_ImageAnnotator_BatchAnnotateImages_sync] diff --git a/owl-bot-staging/v1p2beta1/scripts/fixup_vision_v1p2beta1_keywords.py b/owl-bot-staging/v1p2beta1/scripts/fixup_vision_v1p2beta1_keywords.py new file mode 100644 index 00000000..f9fc39cd --- /dev/null +++ b/owl-bot-staging/v1p2beta1/scripts/fixup_vision_v1p2beta1_keywords.py @@ -0,0 +1,177 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class visionCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'async_batch_annotate_files': ('requests', ), + 'batch_annotate_images': ('requests', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=visionCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the vision client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/owl-bot-staging/v1p2beta1/setup.py b/owl-bot-staging/v1p2beta1/setup.py new file mode 100644 index 00000000..7525c907 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/setup.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import io +import os + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-cloud-vision' + + +description = "Google Cloud Vision API client library" + +version = {} +with open(os.path.join(package_root, 'google/cloud/vision/gapic_version.py')) as fp: + exec(fp.read(), version) +version = version["__version__"] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.0, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "proto-plus >= 1.22.0, <2.0.0dev", + "proto-plus >= 1.22.2, <2.0.0dev; python_version>='3.11'", + "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/python-vision" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.PEP420PackageFinder.find() + if package.startswith("google") +] + +namespaces = ["google", "google.cloud"] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + namespace_packages=namespaces, + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/v1p2beta1/testing/constraints-3.10.txt b/owl-bot-staging/v1p2beta1/testing/constraints-3.10.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p2beta1/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p2beta1/testing/constraints-3.11.txt b/owl-bot-staging/v1p2beta1/testing/constraints-3.11.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p2beta1/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p2beta1/testing/constraints-3.12.txt b/owl-bot-staging/v1p2beta1/testing/constraints-3.12.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p2beta1/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p2beta1/testing/constraints-3.7.txt b/owl-bot-staging/v1p2beta1/testing/constraints-3.7.txt new file mode 100644 index 00000000..6c44adfe --- /dev/null +++ b/owl-bot-staging/v1p2beta1/testing/constraints-3.7.txt @@ -0,0 +1,9 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file. +# Pin the version to the lower bound. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", +# Then this file should have google-cloud-foo==1.14.0 +google-api-core==1.34.0 +proto-plus==1.22.0 +protobuf==3.19.5 diff --git a/owl-bot-staging/v1p2beta1/testing/constraints-3.8.txt b/owl-bot-staging/v1p2beta1/testing/constraints-3.8.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p2beta1/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p2beta1/testing/constraints-3.9.txt b/owl-bot-staging/v1p2beta1/testing/constraints-3.9.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p2beta1/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p2beta1/tests/__init__.py b/owl-bot-staging/v1p2beta1/tests/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p2beta1/tests/unit/__init__.py b/owl-bot-staging/v1p2beta1/tests/unit/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p2beta1/tests/unit/gapic/__init__.py b/owl-bot-staging/v1p2beta1/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p2beta1/tests/unit/gapic/vision_v1p2beta1/__init__.py b/owl-bot-staging/v1p2beta1/tests/unit/gapic/vision_v1p2beta1/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/tests/unit/gapic/vision_v1p2beta1/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p2beta1/tests/unit/gapic/vision_v1p2beta1/test_image_annotator.py b/owl-bot-staging/v1p2beta1/tests/unit/gapic/vision_v1p2beta1/test_image_annotator.py new file mode 100644 index 00000000..4f75b123 --- /dev/null +++ b/owl-bot-staging/v1p2beta1/tests/unit/gapic/vision_v1p2beta1/test_image_annotator.py @@ -0,0 +1,2051 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule +from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.vision_v1p2beta1.services.image_annotator import ImageAnnotatorAsyncClient +from google.cloud.vision_v1p2beta1.services.image_annotator import ImageAnnotatorClient +from google.cloud.vision_v1p2beta1.services.image_annotator import transports +from google.cloud.vision_v1p2beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.type import latlng_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ImageAnnotatorClient._get_default_mtls_endpoint(None) is None + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ImageAnnotatorGrpcTransport, "grpc"), + (transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +def test_image_annotator_client_get_transport_class(): + transport = ImageAnnotatorClient.get_transport_class() + available_transports = [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorRestTransport, + ] + assert transport in available_transports + + transport = ImageAnnotatorClient.get_transport_class("grpc") + assert transport == transports.ImageAnnotatorGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "true"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "false"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "false"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_image_annotator_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + ImageAnnotatorClient, ImageAnnotatorAsyncClient +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", None), +]) +def test_image_annotator_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_image_annotator_client_client_options_from_dict(): + with mock.patch('google.cloud.vision_v1p2beta1.services.image_annotator.transports.ImageAnnotatorGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ImageAnnotatorClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_image_annotator_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=None, + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse( + ) + response = client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + client.batch_annotate_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + +@pytest.mark.asyncio +async def test_batch_annotate_images_async(transport: str = 'grpc_asyncio', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse( + )) + response = await client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +@pytest.mark.asyncio +async def test_batch_annotate_images_async_from_dict(): + await test_batch_annotate_images_async(request_type=dict) + + +def test_batch_annotate_images_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + + +def test_batch_annotate_images_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateFilesRequest, + dict, +]) +def test_async_batch_annotate_files(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.async_batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_async_batch_annotate_files_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + client.async_batch_annotate_files() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_async(transport: str = 'grpc_asyncio', request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.async_batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_async_from_dict(): + await test_async_batch_annotate_files_async(request_type=dict) + + +def test_async_batch_annotate_files_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.async_batch_annotate_files( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + + +def test_async_batch_annotate_files_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.async_batch_annotate_files( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_annotate_images(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_rest_required_fields(request_type=image_annotator.BatchAnnotateImagesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_annotate_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_annotate_images_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_annotate_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_annotate_images_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_batch_annotate_images") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_batch_annotate_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.BatchAnnotateImagesRequest.pb(image_annotator.BatchAnnotateImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = image_annotator.BatchAnnotateImagesResponse.to_json(image_annotator.BatchAnnotateImagesResponse()) + + request = image_annotator.BatchAnnotateImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = image_annotator.BatchAnnotateImagesResponse() + + client.batch_annotate_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_annotate_images_rest_bad_request(transport: str = 'rest', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.batch_annotate_images(request) + + +def test_batch_annotate_images_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_annotate_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p2beta1/images:annotate" % client.transport._host, args[1]) + + +def test_batch_annotate_images_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +def test_batch_annotate_images_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateFilesRequest, + dict, +]) +def test_async_batch_annotate_files_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.async_batch_annotate_files(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_async_batch_annotate_files_rest_required_fields(request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.async_batch_annotate_files(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_async_batch_annotate_files_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.async_batch_annotate_files._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_async_batch_annotate_files_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_async_batch_annotate_files") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_async_batch_annotate_files") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.AsyncBatchAnnotateFilesRequest.pb(image_annotator.AsyncBatchAnnotateFilesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = image_annotator.AsyncBatchAnnotateFilesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.async_batch_annotate_files(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_async_batch_annotate_files_rest_bad_request(transport: str = 'rest', request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.async_batch_annotate_files(request) + + +def test_async_batch_annotate_files_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.async_batch_annotate_files(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p2beta1/files:asyncBatchAnnotate" % client.transport._host, args[1]) + + +def test_async_batch_annotate_files_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +def test_async_batch_annotate_files_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ImageAnnotatorClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "rest", +]) +def test_transport_kind(transport_name): + transport = ImageAnnotatorClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ImageAnnotatorGrpcTransport, + ) + +def test_image_annotator_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_image_annotator_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.vision_v1p2beta1.services.image_annotator.transports.ImageAnnotatorTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'batch_annotate_images', + 'async_batch_annotate_files', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_image_annotator_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.vision_v1p2beta1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id="octopus", + ) + + +def test_image_annotator_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.vision_v1p2beta1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport() + adc.assert_called_once() + + +def test_image_annotator_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ImageAnnotatorClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + ], +) +def test_image_annotator_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-vision',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, + ], +) +def test_image_annotator_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ImageAnnotatorGrpcTransport, grpc_helpers), + (transports.ImageAnnotatorGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_image_annotator_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=["1", "2"], + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_image_annotator_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel") as mock_configure_mtls_channel: + transports.ImageAnnotatorRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_image_annotator_rest_lro_client(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_no_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_with_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_image_annotator_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ImageAnnotatorClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ImageAnnotatorClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.batch_annotate_images._session + session2 = client2.transport.batch_annotate_images._session + assert session1 != session2 + session1 = client1.transport.async_batch_annotate_files._session + session2 = client2.transport.async_batch_annotate_files._session + assert session1 != session2 +def test_image_annotator_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_image_annotator_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_image_annotator_grpc_lro_client(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_image_annotator_grpc_lro_async_client(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ImageAnnotatorClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = ImageAnnotatorClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder, ) + actual = ImageAnnotatorClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = ImageAnnotatorClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ImageAnnotatorClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = ImageAnnotatorClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project, ) + actual = ImageAnnotatorClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = ImageAnnotatorClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ImageAnnotatorClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = ImageAnnotatorClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + transport_class = ImageAnnotatorClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/owl-bot-staging/v1p3beta1/.coveragerc b/owl-bot-staging/v1p3beta1/.coveragerc new file mode 100644 index 00000000..cbf0b85a --- /dev/null +++ b/owl-bot-staging/v1p3beta1/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/vision/__init__.py + google/cloud/vision/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/owl-bot-staging/v1p3beta1/.flake8 b/owl-bot-staging/v1p3beta1/.flake8 new file mode 100644 index 00000000..29227d4c --- /dev/null +++ b/owl-bot-staging/v1p3beta1/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2020 Google LLC +# +# Licensed 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 +# +# https://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. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/owl-bot-staging/v1p3beta1/MANIFEST.in b/owl-bot-staging/v1p3beta1/MANIFEST.in new file mode 100644 index 00000000..5c6705a2 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/vision *.py +recursive-include google/cloud/vision_v1p3beta1 *.py diff --git a/owl-bot-staging/v1p3beta1/README.rst b/owl-bot-staging/v1p3beta1/README.rst new file mode 100644 index 00000000..39f9ca72 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Vision API +================================================= + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. Enable the Google Cloud Vision API. +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a `virtualenv`_ using pip. `virtualenv`_ is a tool to +create isolated Python environments. The basic problem it addresses is one of +dependencies and versions, and indirectly permissions. + +With `virtualenv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ + + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + /bin/pip install /path/to/library + + +Windows +^^^^^^^ + +.. code-block:: console + + python3 -m venv + \Scripts\activate + \Scripts\pip.exe install \path\to\library diff --git a/owl-bot-staging/v1p3beta1/docs/_static/custom.css b/owl-bot-staging/v1p3beta1/docs/_static/custom.css new file mode 100644 index 00000000..06423be0 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/v1p3beta1/docs/conf.py b/owl-bot-staging/v1p3beta1/docs/conf.py new file mode 100644 index 00000000..c75f569a --- /dev/null +++ b/owl-bot-staging/v1p3beta1/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# +# google-cloud-vision documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import shlex + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +__version__ = "0.1.0" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.0.1" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_flags = ["members"] +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# Allow markdown includes (so releases.md can include CHANGLEOG.md) +# http://www.sphinx-doc.org/en/master/markdown.html +source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = u"google-cloud-vision" +copyright = u"2023, Google, LLC" +author = u"Google APIs" # TODO: autogenerate this bit + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for Python", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-cloud-vision-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', + # Latex figure (float) alignment + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + root_doc, + "google-cloud-vision.tex", + u"google-cloud-vision Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + root_doc, + "google-cloud-vision", + u"Google Cloud Vision Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + root_doc, + "google-cloud-vision", + u"google-cloud-vision Documentation", + author, + "google-cloud-vision", + "GAPIC library for Google Cloud Vision API", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("http://python.readthedocs.org/en/latest/", None), + "gax": ("https://gax-python.readthedocs.org/en/latest/", None), + "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), + "google-gax": ("https://gax-python.readthedocs.io/en/latest/", None), + "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None), + "grpc": ("https://grpc.io/grpc/python/", None), + "requests": ("http://requests.kennethreitz.org/en/stable/", None), + "proto": ("https://proto-plus-python.readthedocs.io/en/stable", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/owl-bot-staging/v1p3beta1/docs/index.rst b/owl-bot-staging/v1p3beta1/docs/index.rst new file mode 100644 index 00000000..87acf3ca --- /dev/null +++ b/owl-bot-staging/v1p3beta1/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + vision_v1p3beta1/services + vision_v1p3beta1/types diff --git a/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/image_annotator.rst b/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/image_annotator.rst new file mode 100644 index 00000000..a5ed7542 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/image_annotator.rst @@ -0,0 +1,6 @@ +ImageAnnotator +-------------------------------- + +.. automodule:: google.cloud.vision_v1p3beta1.services.image_annotator + :members: + :inherited-members: diff --git a/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/product_search.rst b/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/product_search.rst new file mode 100644 index 00000000..21e79602 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/product_search.rst @@ -0,0 +1,10 @@ +ProductSearch +------------------------------- + +.. automodule:: google.cloud.vision_v1p3beta1.services.product_search + :members: + :inherited-members: + +.. automodule:: google.cloud.vision_v1p3beta1.services.product_search.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/services.rst b/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/services.rst new file mode 100644 index 00000000..06da9b3d --- /dev/null +++ b/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/services.rst @@ -0,0 +1,7 @@ +Services for Google Cloud Vision v1p3beta1 API +============================================== +.. toctree:: + :maxdepth: 2 + + image_annotator + product_search diff --git a/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/types.rst b/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/types.rst new file mode 100644 index 00000000..8f60a298 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/docs/vision_v1p3beta1/types.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Vision v1p3beta1 API +=========================================== + +.. automodule:: google.cloud.vision_v1p3beta1.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision/__init__.py b/owl-bot-staging/v1p3beta1/google/cloud/vision/__init__.py new file mode 100644 index 00000000..91e9cf55 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision/__init__.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.vision_v1p3beta1.services.image_annotator.client import ImageAnnotatorClient +from google.cloud.vision_v1p3beta1.services.image_annotator.async_client import ImageAnnotatorAsyncClient +from google.cloud.vision_v1p3beta1.services.product_search.client import ProductSearchClient +from google.cloud.vision_v1p3beta1.services.product_search.async_client import ProductSearchAsyncClient + +from google.cloud.vision_v1p3beta1.types.geometry import BoundingPoly +from google.cloud.vision_v1p3beta1.types.geometry import NormalizedVertex +from google.cloud.vision_v1p3beta1.types.geometry import Position +from google.cloud.vision_v1p3beta1.types.geometry import Vertex +from google.cloud.vision_v1p3beta1.types.image_annotator import AnnotateFileResponse +from google.cloud.vision_v1p3beta1.types.image_annotator import AnnotateImageRequest +from google.cloud.vision_v1p3beta1.types.image_annotator import AnnotateImageResponse +from google.cloud.vision_v1p3beta1.types.image_annotator import AsyncAnnotateFileRequest +from google.cloud.vision_v1p3beta1.types.image_annotator import AsyncAnnotateFileResponse +from google.cloud.vision_v1p3beta1.types.image_annotator import AsyncBatchAnnotateFilesRequest +from google.cloud.vision_v1p3beta1.types.image_annotator import AsyncBatchAnnotateFilesResponse +from google.cloud.vision_v1p3beta1.types.image_annotator import BatchAnnotateImagesRequest +from google.cloud.vision_v1p3beta1.types.image_annotator import BatchAnnotateImagesResponse +from google.cloud.vision_v1p3beta1.types.image_annotator import ColorInfo +from google.cloud.vision_v1p3beta1.types.image_annotator import CropHint +from google.cloud.vision_v1p3beta1.types.image_annotator import CropHintsAnnotation +from google.cloud.vision_v1p3beta1.types.image_annotator import CropHintsParams +from google.cloud.vision_v1p3beta1.types.image_annotator import DominantColorsAnnotation +from google.cloud.vision_v1p3beta1.types.image_annotator import EntityAnnotation +from google.cloud.vision_v1p3beta1.types.image_annotator import FaceAnnotation +from google.cloud.vision_v1p3beta1.types.image_annotator import Feature +from google.cloud.vision_v1p3beta1.types.image_annotator import GcsDestination +from google.cloud.vision_v1p3beta1.types.image_annotator import GcsSource +from google.cloud.vision_v1p3beta1.types.image_annotator import Image +from google.cloud.vision_v1p3beta1.types.image_annotator import ImageAnnotationContext +from google.cloud.vision_v1p3beta1.types.image_annotator import ImageContext +from google.cloud.vision_v1p3beta1.types.image_annotator import ImageProperties +from google.cloud.vision_v1p3beta1.types.image_annotator import ImageSource +from google.cloud.vision_v1p3beta1.types.image_annotator import InputConfig +from google.cloud.vision_v1p3beta1.types.image_annotator import LatLongRect +from google.cloud.vision_v1p3beta1.types.image_annotator import LocalizedObjectAnnotation +from google.cloud.vision_v1p3beta1.types.image_annotator import LocationInfo +from google.cloud.vision_v1p3beta1.types.image_annotator import OperationMetadata +from google.cloud.vision_v1p3beta1.types.image_annotator import OutputConfig +from google.cloud.vision_v1p3beta1.types.image_annotator import Property +from google.cloud.vision_v1p3beta1.types.image_annotator import SafeSearchAnnotation +from google.cloud.vision_v1p3beta1.types.image_annotator import TextDetectionParams +from google.cloud.vision_v1p3beta1.types.image_annotator import WebDetectionParams +from google.cloud.vision_v1p3beta1.types.image_annotator import Likelihood +from google.cloud.vision_v1p3beta1.types.product_search import ProductSearchParams +from google.cloud.vision_v1p3beta1.types.product_search import ProductSearchResults +from google.cloud.vision_v1p3beta1.types.product_search_service import AddProductToProductSetRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import BatchOperationMetadata +from google.cloud.vision_v1p3beta1.types.product_search_service import CreateProductRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import CreateProductSetRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import CreateReferenceImageRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import DeleteProductRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import DeleteProductSetRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import DeleteReferenceImageRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import GetProductRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import GetProductSetRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import GetReferenceImageRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import ImportProductSetsGcsSource +from google.cloud.vision_v1p3beta1.types.product_search_service import ImportProductSetsInputConfig +from google.cloud.vision_v1p3beta1.types.product_search_service import ImportProductSetsRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import ImportProductSetsResponse +from google.cloud.vision_v1p3beta1.types.product_search_service import ListProductSetsRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import ListProductSetsResponse +from google.cloud.vision_v1p3beta1.types.product_search_service import ListProductsInProductSetRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import ListProductsInProductSetResponse +from google.cloud.vision_v1p3beta1.types.product_search_service import ListProductsRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import ListProductsResponse +from google.cloud.vision_v1p3beta1.types.product_search_service import ListReferenceImagesRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import ListReferenceImagesResponse +from google.cloud.vision_v1p3beta1.types.product_search_service import Product +from google.cloud.vision_v1p3beta1.types.product_search_service import ProductSet +from google.cloud.vision_v1p3beta1.types.product_search_service import ReferenceImage +from google.cloud.vision_v1p3beta1.types.product_search_service import RemoveProductFromProductSetRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import UpdateProductRequest +from google.cloud.vision_v1p3beta1.types.product_search_service import UpdateProductSetRequest +from google.cloud.vision_v1p3beta1.types.text_annotation import Block +from google.cloud.vision_v1p3beta1.types.text_annotation import Page +from google.cloud.vision_v1p3beta1.types.text_annotation import Paragraph +from google.cloud.vision_v1p3beta1.types.text_annotation import Symbol +from google.cloud.vision_v1p3beta1.types.text_annotation import TextAnnotation +from google.cloud.vision_v1p3beta1.types.text_annotation import Word +from google.cloud.vision_v1p3beta1.types.web_detection import WebDetection + +__all__ = ('ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', + 'ProductSearchClient', + 'ProductSearchAsyncClient', + 'BoundingPoly', + 'NormalizedVertex', + 'Position', + 'Vertex', + 'AnnotateFileResponse', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'GcsDestination', + 'GcsSource', + 'Image', + 'ImageAnnotationContext', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'InputConfig', + 'LatLongRect', + 'LocalizedObjectAnnotation', + 'LocationInfo', + 'OperationMetadata', + 'OutputConfig', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'ProductSearchParams', + 'ProductSearchResults', + 'AddProductToProductSetRequest', + 'BatchOperationMetadata', + 'CreateProductRequest', + 'CreateProductSetRequest', + 'CreateReferenceImageRequest', + 'DeleteProductRequest', + 'DeleteProductSetRequest', + 'DeleteReferenceImageRequest', + 'GetProductRequest', + 'GetProductSetRequest', + 'GetReferenceImageRequest', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ListProductsRequest', + 'ListProductsResponse', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'Product', + 'ProductSet', + 'ReferenceImage', + 'RemoveProductFromProductSetRequest', + 'UpdateProductRequest', + 'UpdateProductSetRequest', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision/gapic_version.py b/owl-bot-staging/v1p3beta1/google/cloud/vision/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision/py.typed b/owl-bot-staging/v1p3beta1/google/cloud/vision/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/__init__.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/__init__.py new file mode 100644 index 00000000..1af8d681 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/__init__.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision_v1p3beta1 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.image_annotator import ImageAnnotatorClient +from .services.image_annotator import ImageAnnotatorAsyncClient +from .services.product_search import ProductSearchClient +from .services.product_search import ProductSearchAsyncClient + +from .types.geometry import BoundingPoly +from .types.geometry import NormalizedVertex +from .types.geometry import Position +from .types.geometry import Vertex +from .types.image_annotator import AnnotateFileResponse +from .types.image_annotator import AnnotateImageRequest +from .types.image_annotator import AnnotateImageResponse +from .types.image_annotator import AsyncAnnotateFileRequest +from .types.image_annotator import AsyncAnnotateFileResponse +from .types.image_annotator import AsyncBatchAnnotateFilesRequest +from .types.image_annotator import AsyncBatchAnnotateFilesResponse +from .types.image_annotator import BatchAnnotateImagesRequest +from .types.image_annotator import BatchAnnotateImagesResponse +from .types.image_annotator import ColorInfo +from .types.image_annotator import CropHint +from .types.image_annotator import CropHintsAnnotation +from .types.image_annotator import CropHintsParams +from .types.image_annotator import DominantColorsAnnotation +from .types.image_annotator import EntityAnnotation +from .types.image_annotator import FaceAnnotation +from .types.image_annotator import Feature +from .types.image_annotator import GcsDestination +from .types.image_annotator import GcsSource +from .types.image_annotator import Image +from .types.image_annotator import ImageAnnotationContext +from .types.image_annotator import ImageContext +from .types.image_annotator import ImageProperties +from .types.image_annotator import ImageSource +from .types.image_annotator import InputConfig +from .types.image_annotator import LatLongRect +from .types.image_annotator import LocalizedObjectAnnotation +from .types.image_annotator import LocationInfo +from .types.image_annotator import OperationMetadata +from .types.image_annotator import OutputConfig +from .types.image_annotator import Property +from .types.image_annotator import SafeSearchAnnotation +from .types.image_annotator import TextDetectionParams +from .types.image_annotator import WebDetectionParams +from .types.image_annotator import Likelihood +from .types.product_search import ProductSearchParams +from .types.product_search import ProductSearchResults +from .types.product_search_service import AddProductToProductSetRequest +from .types.product_search_service import BatchOperationMetadata +from .types.product_search_service import CreateProductRequest +from .types.product_search_service import CreateProductSetRequest +from .types.product_search_service import CreateReferenceImageRequest +from .types.product_search_service import DeleteProductRequest +from .types.product_search_service import DeleteProductSetRequest +from .types.product_search_service import DeleteReferenceImageRequest +from .types.product_search_service import GetProductRequest +from .types.product_search_service import GetProductSetRequest +from .types.product_search_service import GetReferenceImageRequest +from .types.product_search_service import ImportProductSetsGcsSource +from .types.product_search_service import ImportProductSetsInputConfig +from .types.product_search_service import ImportProductSetsRequest +from .types.product_search_service import ImportProductSetsResponse +from .types.product_search_service import ListProductSetsRequest +from .types.product_search_service import ListProductSetsResponse +from .types.product_search_service import ListProductsInProductSetRequest +from .types.product_search_service import ListProductsInProductSetResponse +from .types.product_search_service import ListProductsRequest +from .types.product_search_service import ListProductsResponse +from .types.product_search_service import ListReferenceImagesRequest +from .types.product_search_service import ListReferenceImagesResponse +from .types.product_search_service import Product +from .types.product_search_service import ProductSet +from .types.product_search_service import ReferenceImage +from .types.product_search_service import RemoveProductFromProductSetRequest +from .types.product_search_service import UpdateProductRequest +from .types.product_search_service import UpdateProductSetRequest +from .types.text_annotation import Block +from .types.text_annotation import Page +from .types.text_annotation import Paragraph +from .types.text_annotation import Symbol +from .types.text_annotation import TextAnnotation +from .types.text_annotation import Word +from .types.web_detection import WebDetection + +__all__ = ( + 'ImageAnnotatorAsyncClient', + 'ProductSearchAsyncClient', +'AddProductToProductSetRequest', +'AnnotateFileResponse', +'AnnotateImageRequest', +'AnnotateImageResponse', +'AsyncAnnotateFileRequest', +'AsyncAnnotateFileResponse', +'AsyncBatchAnnotateFilesRequest', +'AsyncBatchAnnotateFilesResponse', +'BatchAnnotateImagesRequest', +'BatchAnnotateImagesResponse', +'BatchOperationMetadata', +'Block', +'BoundingPoly', +'ColorInfo', +'CreateProductRequest', +'CreateProductSetRequest', +'CreateReferenceImageRequest', +'CropHint', +'CropHintsAnnotation', +'CropHintsParams', +'DeleteProductRequest', +'DeleteProductSetRequest', +'DeleteReferenceImageRequest', +'DominantColorsAnnotation', +'EntityAnnotation', +'FaceAnnotation', +'Feature', +'GcsDestination', +'GcsSource', +'GetProductRequest', +'GetProductSetRequest', +'GetReferenceImageRequest', +'Image', +'ImageAnnotationContext', +'ImageAnnotatorClient', +'ImageContext', +'ImageProperties', +'ImageSource', +'ImportProductSetsGcsSource', +'ImportProductSetsInputConfig', +'ImportProductSetsRequest', +'ImportProductSetsResponse', +'InputConfig', +'LatLongRect', +'Likelihood', +'ListProductSetsRequest', +'ListProductSetsResponse', +'ListProductsInProductSetRequest', +'ListProductsInProductSetResponse', +'ListProductsRequest', +'ListProductsResponse', +'ListReferenceImagesRequest', +'ListReferenceImagesResponse', +'LocalizedObjectAnnotation', +'LocationInfo', +'NormalizedVertex', +'OperationMetadata', +'OutputConfig', +'Page', +'Paragraph', +'Position', +'Product', +'ProductSearchClient', +'ProductSearchParams', +'ProductSearchResults', +'ProductSet', +'Property', +'ReferenceImage', +'RemoveProductFromProductSetRequest', +'SafeSearchAnnotation', +'Symbol', +'TextAnnotation', +'TextDetectionParams', +'UpdateProductRequest', +'UpdateProductSetRequest', +'Vertex', +'WebDetection', +'WebDetectionParams', +'Word', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/gapic_metadata.json b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/gapic_metadata.json new file mode 100644 index 00000000..5c3d49fd --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/gapic_metadata.json @@ -0,0 +1,347 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.vision_v1p3beta1", + "protoPackage": "google.cloud.vision.v1p3beta1", + "schema": "1.0", + "services": { + "ImageAnnotator": { + "clients": { + "grpc": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ImageAnnotatorAsyncClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "rest": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + } + } + }, + "ProductSearch": { + "clients": { + "grpc": { + "libraryClient": "ProductSearchClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ProductSearchAsyncClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + }, + "rest": { + "libraryClient": "ProductSearchClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/gapic_version.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/py.typed b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/__init__.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/__init__.py new file mode 100644 index 00000000..89a37dc9 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/__init__.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/__init__.py new file mode 100644 index 00000000..ee708f26 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .client import ImageAnnotatorClient +from .async_client import ImageAnnotatorAsyncClient + +__all__ = ( + 'ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/async_client.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/async_client.py new file mode 100644 index 00000000..45053b51 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/async_client.py @@ -0,0 +1,424 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.vision_v1p3beta1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p3beta1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .client import ImageAnnotatorClient + + +class ImageAnnotatorAsyncClient: + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + _client: ImageAnnotatorClient + + DEFAULT_ENDPOINT = ImageAnnotatorClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ImageAnnotatorClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(ImageAnnotatorClient.product_path) + parse_product_path = staticmethod(ImageAnnotatorClient.parse_product_path) + product_set_path = staticmethod(ImageAnnotatorClient.product_set_path) + parse_product_set_path = staticmethod(ImageAnnotatorClient.parse_product_set_path) + common_billing_account_path = staticmethod(ImageAnnotatorClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ImageAnnotatorClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ImageAnnotatorClient.common_folder_path) + parse_common_folder_path = staticmethod(ImageAnnotatorClient.parse_common_folder_path) + common_organization_path = staticmethod(ImageAnnotatorClient.common_organization_path) + parse_common_organization_path = staticmethod(ImageAnnotatorClient.parse_common_organization_path) + common_project_path = staticmethod(ImageAnnotatorClient.common_project_path) + parse_common_project_path = staticmethod(ImageAnnotatorClient.parse_common_project_path) + common_location_path = staticmethod(ImageAnnotatorClient.common_location_path) + parse_common_location_path = staticmethod(ImageAnnotatorClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_info.__func__(ImageAnnotatorAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_file.__func__(ImageAnnotatorAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ImageAnnotatorClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ImageAnnotatorClient).get_transport_class, type(ImageAnnotatorClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ImageAnnotatorTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ImageAnnotatorClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_batch_annotate_images(): + # Create a client + client = vision_v1p3beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.BatchAnnotateImagesRequest, dict]]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (:class:`MutableSequence[google.cloud.vision_v1p3beta1.types.AnnotateImageRequest]`): + Individual image annotation requests + for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.BatchAnnotateImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def async_batch_annotate_files(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AsyncAnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p3beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.AsyncBatchAnnotateFilesRequest, dict]]): + The request object. Multiple async file annotation + requests are batched into a single + service call. + requests (:class:`MutableSequence[google.cloud.vision_v1p3beta1.types.AsyncAnnotateFileRequest]`): + Required. Individual async file + annotation requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p3beta1.types.AsyncBatchAnnotateFilesResponse` + Response to an async batch file annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.AsyncBatchAnnotateFilesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.async_batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + image_annotator.AsyncBatchAnnotateFilesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ImageAnnotatorAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorAsyncClient", +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/client.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/client.py new file mode 100644 index 00000000..2d07d4c6 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/client.py @@ -0,0 +1,625 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import os +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast + +from google.cloud.vision_v1p3beta1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p3beta1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ImageAnnotatorGrpcTransport +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .transports.rest import ImageAnnotatorRestTransport + + +class ImageAnnotatorClientMeta(type): + """Metaclass for the ImageAnnotator client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] + _transport_registry["grpc"] = ImageAnnotatorGrpcTransport + _transport_registry["grpc_asyncio"] = ImageAnnotatorGrpcAsyncIOTransport + _transport_registry["rest"] = ImageAnnotatorRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ImageAnnotatorTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ImageAnnotatorClient(metaclass=ImageAnnotatorClientMeta): + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "vision.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_set_path(project: str,location: str,product_set: str,) -> str: + """Returns a fully-qualified product_set string.""" + return "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + + @staticmethod + def parse_product_set_path(path: str) -> Dict[str,str]: + """Parses a product_set path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/productSets/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ImageAnnotatorTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ImageAnnotatorTransport): + # transport is a ImageAnnotatorTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_batch_annotate_images(): + # Create a client + client = vision_v1p3beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.BatchAnnotateImagesRequest, dict]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (MutableSequence[google.cloud.vision_v1p3beta1.types.AnnotateImageRequest]): + Individual image annotation requests + for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.BatchAnnotateImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.BatchAnnotateImagesRequest): + request = image_annotator.BatchAnnotateImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_annotate_images] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def async_batch_annotate_files(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AsyncAnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p3beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.AsyncBatchAnnotateFilesRequest, dict]): + The request object. Multiple async file annotation + requests are batched into a single + service call. + requests (MutableSequence[google.cloud.vision_v1p3beta1.types.AsyncAnnotateFileRequest]): + Required. Individual async file + annotation requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p3beta1.types.AsyncBatchAnnotateFilesResponse` + Response to an async batch file annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.AsyncBatchAnnotateFilesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.AsyncBatchAnnotateFilesRequest): + request = image_annotator.AsyncBatchAnnotateFilesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.async_batch_annotate_files] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + image_annotator.AsyncBatchAnnotateFilesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ImageAnnotatorClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorClient", +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/__init__.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/__init__.py new file mode 100644 index 00000000..ad6cf948 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +from typing import Dict, Type + +from .base import ImageAnnotatorTransport +from .grpc import ImageAnnotatorGrpcTransport +from .grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .rest import ImageAnnotatorRestTransport +from .rest import ImageAnnotatorRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] +_transport_registry['grpc'] = ImageAnnotatorGrpcTransport +_transport_registry['grpc_asyncio'] = ImageAnnotatorGrpcAsyncIOTransport +_transport_registry['rest'] = ImageAnnotatorRestTransport + +__all__ = ( + 'ImageAnnotatorTransport', + 'ImageAnnotatorGrpcTransport', + 'ImageAnnotatorGrpcAsyncIOTransport', + 'ImageAnnotatorRestTransport', + 'ImageAnnotatorRestInterceptor', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/base.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/base.py new file mode 100644 index 00000000..c3e9060d --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/base.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.vision_v1p3beta1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.vision_v1p3beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ImageAnnotatorTransport(abc.ABC): + """Abstract transport class for ImageAnnotator.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', + ) + + DEFAULT_HOST: str = 'vision.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience(api_audience if api_audience else host) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.batch_annotate_images: gapic_v1.method.wrap_method( + self.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.async_batch_annotate_files: gapic_v1.method.wrap_method( + self.async_batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Union[ + image_annotator.BatchAnnotateImagesResponse, + Awaitable[image_annotator.BatchAnnotateImagesResponse] + ]]: + raise NotImplementedError() + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ImageAnnotatorTransport', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/grpc.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/grpc.py new file mode 100644 index 00000000..d07d36ed --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/grpc.py @@ -0,0 +1,319 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.vision_v1p3beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO + + +class ImageAnnotatorGrpcTransport(ImageAnnotatorTransport): + """gRPC backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + ~.BatchAnnotateImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + operations_pb2.Operation]: + r"""Return a callable for the async batch annotate files method over gRPC. + + Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + Returns: + Callable[[~.AsyncBatchAnnotateFilesRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_files' not in self._stubs: + self._stubs['async_batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ImageAnnotator/AsyncBatchAnnotateFiles', + request_serializer=image_annotator.AsyncBatchAnnotateFilesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_files'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ImageAnnotatorGrpcTransport', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/grpc_asyncio.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/grpc_asyncio.py new file mode 100644 index 00000000..b328dffe --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/grpc_asyncio.py @@ -0,0 +1,318 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.vision_v1p3beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .grpc import ImageAnnotatorGrpcTransport + + +class ImageAnnotatorGrpcAsyncIOTransport(ImageAnnotatorTransport): + """gRPC AsyncIO backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Awaitable[image_annotator.BatchAnnotateImagesResponse]]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + Awaitable[~.BatchAnnotateImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the async batch annotate files method over gRPC. + + Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + Returns: + Callable[[~.AsyncBatchAnnotateFilesRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_files' not in self._stubs: + self._stubs['async_batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ImageAnnotator/AsyncBatchAnnotateFiles', + request_serializer=image_annotator.AsyncBatchAnnotateFilesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_files'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ImageAnnotatorGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/rest.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/rest.py new file mode 100644 index 00000000..7328a672 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/image_annotator/transports/rest.py @@ -0,0 +1,454 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.auth.transport.requests import AuthorizedSession # type: ignore +import json # type: ignore +import grpc # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.api_core import rest_helpers +from google.api_core import rest_streaming +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from google.api_core import operations_v1 +from requests import __version__ as requests_version +import dataclasses +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.cloud.vision_v1p3beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore + +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ImageAnnotatorRestInterceptor: + """Interceptor for ImageAnnotator. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ImageAnnotatorRestTransport. + + .. code-block:: python + class MyCustomImageAnnotatorInterceptor(ImageAnnotatorRestInterceptor): + def pre_async_batch_annotate_files(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_async_batch_annotate_files(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_annotate_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_annotate_images(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ImageAnnotatorRestTransport(interceptor=MyCustomImageAnnotatorInterceptor()) + client = ImageAnnotatorClient(transport=transport) + + + """ + def pre_async_batch_annotate_files(self, request: image_annotator.AsyncBatchAnnotateFilesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.AsyncBatchAnnotateFilesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for async_batch_annotate_files + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_async_batch_annotate_files(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for async_batch_annotate_files + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + def pre_batch_annotate_images(self, request: image_annotator.BatchAnnotateImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.BatchAnnotateImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_batch_annotate_images(self, response: image_annotator.BatchAnnotateImagesResponse) -> image_annotator.BatchAnnotateImagesResponse: + """Post-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ImageAnnotatorRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ImageAnnotatorRestInterceptor + + +class ImageAnnotatorRestTransport(ImageAnnotatorTransport): + """REST backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[ + ], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + interceptor: Optional[ImageAnnotatorRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError(f"Unexpected hostname structure: {host}") # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ImageAnnotatorRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1p3beta1") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AsyncBatchAnnotateFiles(ImageAnnotatorRestStub): + def __hash__(self): + return hash("AsyncBatchAnnotateFiles") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.AsyncBatchAnnotateFilesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the async batch annotate + files method over HTTP. + + Args: + request (~.image_annotator.AsyncBatchAnnotateFilesRequest): + The request object. Multiple async file annotation + requests are batched into a single + service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p3beta1/files:asyncBatchAnnotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_async_batch_annotate_files(request, metadata) + pb_request = image_annotator.AsyncBatchAnnotateFilesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_async_batch_annotate_files(resp) + return resp + + class _BatchAnnotateImages(ImageAnnotatorRestStub): + def __hash__(self): + return hash("BatchAnnotateImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.BatchAnnotateImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Call the batch annotate images method over HTTP. + + Args: + request (~.image_annotator.BatchAnnotateImagesRequest): + The request object. Multiple image annotation requests + are batched into a single service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.image_annotator.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p3beta1/images:annotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_annotate_images(request, metadata) + pb_request = image_annotator.BatchAnnotateImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = image_annotator.BatchAnnotateImagesResponse() + pb_resp = image_annotator.BatchAnnotateImagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_annotate_images(resp) + return resp + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AsyncBatchAnnotateFiles(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchAnnotateImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ImageAnnotatorRestTransport', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/__init__.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/__init__.py new file mode 100644 index 00000000..f48c4b91 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .client import ProductSearchClient +from .async_client import ProductSearchAsyncClient + +__all__ = ( + 'ProductSearchClient', + 'ProductSearchAsyncClient', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/async_client.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/async_client.py new file mode 100644 index 00000000..3aa1f812 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/async_client.py @@ -0,0 +1,2471 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.vision_v1p3beta1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p3beta1.services.product_search import pagers +from google.cloud.vision_v1p3beta1.types import geometry +from google.cloud.vision_v1p3beta1.types import product_search_service +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .client import ProductSearchClient + + +class ProductSearchAsyncClient: + """Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p3beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p3beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + """ + + _client: ProductSearchClient + + DEFAULT_ENDPOINT = ProductSearchClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ProductSearchClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(ProductSearchClient.product_path) + parse_product_path = staticmethod(ProductSearchClient.parse_product_path) + product_set_path = staticmethod(ProductSearchClient.product_set_path) + parse_product_set_path = staticmethod(ProductSearchClient.parse_product_set_path) + reference_image_path = staticmethod(ProductSearchClient.reference_image_path) + parse_reference_image_path = staticmethod(ProductSearchClient.parse_reference_image_path) + common_billing_account_path = staticmethod(ProductSearchClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ProductSearchClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ProductSearchClient.common_folder_path) + parse_common_folder_path = staticmethod(ProductSearchClient.parse_common_folder_path) + common_organization_path = staticmethod(ProductSearchClient.common_organization_path) + parse_common_organization_path = staticmethod(ProductSearchClient.parse_common_organization_path) + common_project_path = staticmethod(ProductSearchClient.common_project_path) + parse_common_project_path = staticmethod(ProductSearchClient.parse_common_project_path) + common_location_path = staticmethod(ProductSearchClient.common_location_path) + parse_common_location_path = staticmethod(ProductSearchClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchAsyncClient: The constructed client. + """ + return ProductSearchClient.from_service_account_info.__func__(ProductSearchAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchAsyncClient: The constructed client. + """ + return ProductSearchClient.from_service_account_file.__func__(ProductSearchAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ProductSearchClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductSearchTransport: + """Returns the transport used by the client instance. + + Returns: + ProductSearchTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ProductSearchClient).get_transport_class, type(ProductSearchClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ProductSearchTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product search client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ProductSearchTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ProductSearchClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_product_set(self, + request: Optional[Union[product_search_service.CreateProductSetRequest, dict]] = None, + *, + parent: Optional[str] = None, + product_set: Optional[product_search_service.ProductSet] = None, + product_set_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_create_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.CreateProductSetRequest, dict]]): + The request object. Request message for the ``CreateProductSet`` method. + parent (:class:`str`): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set (:class:`google.cloud.vision_v1p3beta1.types.ProductSet`): + Required. The ProductSet to create. + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set_id (:class:`str`): + A user-supplied resource id for this ProductSet. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_set_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product_set, product_set_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product_set is not None: + request.product_set = product_set + if product_set_id is not None: + request.product_set_id = product_set_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_product_sets(self, + request: Optional[Union[product_search_service.ListProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductSetsAsyncPager: + r"""Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_list_product_sets(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.ListProductSetsRequest, dict]]): + The request object. Request message for the ``ListProductSets`` method. + parent (:class:`str`): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductSetsAsyncPager: + Response message for the ListProductSets method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductSetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductSetsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_product_set(self, + request: Optional[Union[product_search_service.GetProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_get_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.GetProductSetRequest, dict]]): + The request object. Request message for the ``GetProductSet`` method. + name (:class:`str`): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_product_set(self, + request: Optional[Union[product_search_service.UpdateProductSetRequest, dict]] = None, + *, + product_set: Optional[product_search_service.ProductSet] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_update_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.UpdateProductSetRequest( + ) + + # Make the request + response = await client.update_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.UpdateProductSetRequest, dict]]): + The request object. Request message for the ``UpdateProductSet`` method. + product_set (:class:`google.cloud.vision_v1p3beta1.types.ProductSet`): + Required. The ProductSet resource + which replaces the one on the server. + + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask path is ``display_name``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product_set, update_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.UpdateProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product_set is not None: + request.product_set = product_set + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product_set.name", request.product_set.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_product_set(self, + request: Optional[Union[product_search_service.DeleteProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a ProductSet. All Products and + ReferenceImages in the ProductSet will be deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_delete_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + await client.delete_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.DeleteProductSetRequest, dict]]): + The request object. Request message for the ``DeleteProductSet`` method. + name (:class:`str`): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def create_product(self, + request: Optional[Union[product_search_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[product_search_service.Product] = None, + product_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_create_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.CreateProductRequest, dict]]): + The request object. Request message for the ``CreateProduct`` method. + parent (:class:`str`): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`google.cloud.vision_v1p3beta1.types.Product`): + Required. The product to create. + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_id (:class:`str`): + A user-supplied resource id for this Product. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product, product_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product is not None: + request.product = product + if product_id is not None: + request.product_id = product_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_products(self, + request: Optional[Union[product_search_service.ListProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsAsyncPager: + r"""Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_list_products(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.ListProductsRequest, dict]]): + The request object. Request message for the ``ListProducts`` method. + parent (:class:`str`): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductsAsyncPager: + Response message for the ListProducts method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_products, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_product(self, + request: Optional[Union[product_search_service.GetProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_get_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.GetProductRequest, dict]]): + The request object. Request message for the ``GetProduct`` method. + name (:class:`str`): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_product(self, + request: Optional[Union[product_search_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[product_search_service.Product] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Makes changes to a Product resource. Only display_name, + description and labels can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_update_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.UpdateProductRequest( + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.UpdateProductRequest, dict]]): + The request object. Request message for the ``UpdateProduct`` method. + product (:class:`google.cloud.vision_v1p3beta1.types.Product`): + Required. The Product resource which + replaces the one on the server. + product.name is immutable. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask paths include ``product_labels``, ``display_name``, + and ``description``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product, update_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.UpdateProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product.name", request.product.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_product(self, + request: Optional[Union[product_search_service.DeleteProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a product and its reference images. + + Metadata of the product and all its images will be deleted right + away, but search queries against ProductSets containing the + product may still work until all related caches are refreshed. + + Possible errors: + + - Returns NOT_FOUND if the product does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_delete_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.DeleteProductRequest, dict]]): + The request object. Request message for the ``DeleteProduct`` method. + name (:class:`str`): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def create_reference_image(self, + request: Optional[Union[product_search_service.CreateReferenceImageRequest, dict]] = None, + *, + parent: Optional[str] = None, + reference_image: Optional[product_search_service.ReferenceImage] = None, + reference_image_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_create_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + reference_image = vision_v1p3beta1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1p3beta1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = await client.create_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.CreateReferenceImageRequest, dict]]): + The request object. Request message for the ``CreateReferenceImage`` method. + parent (:class:`str`): + Required. Resource name of the product in which to + create the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image (:class:`google.cloud.vision_v1p3beta1.types.ReferenceImage`): + Required. The reference image to + create. If an image ID is specified, it + is ignored. + + This corresponds to the ``reference_image`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image_id (:class:`str`): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value + as the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``reference_image_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, reference_image, reference_image_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if reference_image is not None: + request.reference_image = reference_image + if reference_image_id is not None: + request.reference_image_id = reference_image_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_reference_image(self, + request: Optional[Union[product_search_service.DeleteReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a reference image. + + The image metadata will be deleted right away, but search + queries against ProductSets containing the image may still work + until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + Possible errors: + + - Returns NOT_FOUND if the reference image does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_delete_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + await client.delete_reference_image(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.DeleteReferenceImageRequest, dict]]): + The request object. Request message for the ``DeleteReferenceImage`` method. + name (:class:`str`): + Required. The resource name of the reference image to + delete. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_reference_images(self, + request: Optional[Union[product_search_service.ListReferenceImagesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListReferenceImagesAsyncPager: + r"""Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_list_reference_images(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.ListReferenceImagesRequest, dict]]): + The request object. Request message for the ``ListReferenceImages`` method. + parent (:class:`str`): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.services.product_search.pagers.ListReferenceImagesAsyncPager: + Response message for the ListReferenceImages method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListReferenceImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_reference_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListReferenceImagesAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_reference_image(self, + request: Optional[Union[product_search_service.GetReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_get_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = await client.get_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.GetReferenceImageRequest, dict]]): + The request object. Request message for the ``GetReferenceImage`` method. + name (:class:`str`): + Required. The resource name of the ReferenceImage to + get. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_product_to_product_set(self, + request: Optional[Union[product_search_service.AddProductToProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_add_product_to_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.add_product_to_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.AddProductToProductSetRequest, dict]]): + The request object. Request message for the ``AddProductToProductSet`` + method. + name (:class:`str`): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`str`): + Required. The resource name for the Product to be added + to this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.AddProductToProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.add_product_to_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def remove_product_from_product_set(self, + request: Optional[Union[product_search_service.RemoveProductFromProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Removes a Product from the specified ProductSet. + + Possible errors: + + - Returns NOT_FOUND If the Product is not found under the + ProductSet. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.remove_product_from_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.RemoveProductFromProductSetRequest, dict]]): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + name (:class:`str`): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`str`): + Required. The resource name for the Product to be + removed from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.RemoveProductFromProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.remove_product_from_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_products_in_product_set(self, + request: Optional[Union[product_search_service.ListProductsInProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsInProductSetAsyncPager: + r"""Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_list_products_in_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.ListProductsInProductSetRequest, dict]]): + The request object. Request message for the ``ListProductsInProductSet`` + method. + name (:class:`str`): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductsInProductSetAsyncPager: + Response message for the ListProductsInProductSet + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductsInProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_products_in_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductsInProductSetAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def import_product_sets(self, + request: Optional[Union[product_search_service.ImportProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + input_config: Optional[product_search_service.ImportProductSetsInputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + async def sample_import_product_sets(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p3beta1.types.ImportProductSetsRequest, dict]]): + The request object. Request message for the ``ImportProductSets`` method. + parent (:class:`str`): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + input_config (:class:`google.cloud.vision_v1p3beta1.types.ImportProductSetsInputConfig`): + Required. The input content for the + list of requests. + + This corresponds to the ``input_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p3beta1.types.ImportProductSetsResponse` + Response message for the ImportProductSets method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, input_config]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ImportProductSetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if input_config is not None: + request.input_config = input_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + product_search_service.ImportProductSetsResponse, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ProductSearchAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductSearchAsyncClient", +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/client.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/client.py new file mode 100644 index 00000000..7430a0bc --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/client.py @@ -0,0 +1,2583 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import os +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast + +from google.cloud.vision_v1p3beta1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p3beta1.services.product_search import pagers +from google.cloud.vision_v1p3beta1.types import geometry +from google.cloud.vision_v1p3beta1.types import product_search_service +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ProductSearchGrpcTransport +from .transports.grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .transports.rest import ProductSearchRestTransport + + +class ProductSearchClientMeta(type): + """Metaclass for the ProductSearch client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ProductSearchTransport]] + _transport_registry["grpc"] = ProductSearchGrpcTransport + _transport_registry["grpc_asyncio"] = ProductSearchGrpcAsyncIOTransport + _transport_registry["rest"] = ProductSearchRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ProductSearchTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ProductSearchClient(metaclass=ProductSearchClientMeta): + """Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p3beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p3beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "vision.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ProductSearchTransport: + """Returns the transport used by the client instance. + + Returns: + ProductSearchTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_set_path(project: str,location: str,product_set: str,) -> str: + """Returns a fully-qualified product_set string.""" + return "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + + @staticmethod + def parse_product_set_path(path: str) -> Dict[str,str]: + """Parses a product_set path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/productSets/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def reference_image_path(project: str,location: str,product: str,reference_image: str,) -> str: + """Returns a fully-qualified reference_image string.""" + return "projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}".format(project=project, location=location, product=product, reference_image=reference_image, ) + + @staticmethod + def parse_reference_image_path(path: str) -> Dict[str,str]: + """Parses a reference_image path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)/referenceImages/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ProductSearchTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product search client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ProductSearchTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ProductSearchTransport): + # transport is a ProductSearchTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def create_product_set(self, + request: Optional[Union[product_search_service.CreateProductSetRequest, dict]] = None, + *, + parent: Optional[str] = None, + product_set: Optional[product_search_service.ProductSet] = None, + product_set_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_create_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.CreateProductSetRequest, dict]): + The request object. Request message for the ``CreateProductSet`` method. + parent (str): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set (google.cloud.vision_v1p3beta1.types.ProductSet): + Required. The ProductSet to create. + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set_id (str): + A user-supplied resource id for this ProductSet. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_set_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product_set, product_set_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateProductSetRequest): + request = product_search_service.CreateProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product_set is not None: + request.product_set = product_set + if product_set_id is not None: + request.product_set_id = product_set_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_product_sets(self, + request: Optional[Union[product_search_service.ListProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductSetsPager: + r"""Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_list_product_sets(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.ListProductSetsRequest, dict]): + The request object. Request message for the ``ListProductSets`` method. + parent (str): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductSetsPager: + Response message for the ListProductSets method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductSetsRequest): + request = product_search_service.ListProductSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_product_sets] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductSetsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_product_set(self, + request: Optional[Union[product_search_service.GetProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_get_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = client.get_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.GetProductSetRequest, dict]): + The request object. Request message for the ``GetProductSet`` method. + name (str): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetProductSetRequest): + request = product_search_service.GetProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_product_set(self, + request: Optional[Union[product_search_service.UpdateProductSetRequest, dict]] = None, + *, + product_set: Optional[product_search_service.ProductSet] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_update_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.UpdateProductSetRequest( + ) + + # Make the request + response = client.update_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.UpdateProductSetRequest, dict]): + The request object. Request message for the ``UpdateProductSet`` method. + product_set (google.cloud.vision_v1p3beta1.types.ProductSet): + Required. The ProductSet resource + which replaces the one on the server. + + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask path is ``display_name``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product_set, update_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.UpdateProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.UpdateProductSetRequest): + request = product_search_service.UpdateProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product_set is not None: + request.product_set = product_set + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product_set.name", request.product_set.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_product_set(self, + request: Optional[Union[product_search_service.DeleteProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a ProductSet. All Products and + ReferenceImages in the ProductSet will be deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_delete_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + client.delete_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.DeleteProductSetRequest, dict]): + The request object. Request message for the ``DeleteProductSet`` method. + name (str): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteProductSetRequest): + request = product_search_service.DeleteProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def create_product(self, + request: Optional[Union[product_search_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[product_search_service.Product] = None, + product_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_create_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.CreateProductRequest, dict]): + The request object. Request message for the ``CreateProduct`` method. + parent (str): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (google.cloud.vision_v1p3beta1.types.Product): + Required. The product to create. + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_id (str): + A user-supplied resource id for this Product. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product, product_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateProductRequest): + request = product_search_service.CreateProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product is not None: + request.product = product + if product_id is not None: + request.product_id = product_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_products(self, + request: Optional[Union[product_search_service.ListProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsPager: + r"""Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_list_products(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.ListProductsRequest, dict]): + The request object. Request message for the ``ListProducts`` method. + parent (str): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductsPager: + Response message for the ListProducts method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductsRequest): + request = product_search_service.ListProductsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_products] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_product(self, + request: Optional[Union[product_search_service.GetProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_get_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.GetProductRequest, dict]): + The request object. Request message for the ``GetProduct`` method. + name (str): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetProductRequest): + request = product_search_service.GetProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_product(self, + request: Optional[Union[product_search_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[product_search_service.Product] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Makes changes to a Product resource. Only display_name, + description and labels can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_update_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.UpdateProductRequest( + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.UpdateProductRequest, dict]): + The request object. Request message for the ``UpdateProduct`` method. + product (google.cloud.vision_v1p3beta1.types.Product): + Required. The Product resource which + replaces the one on the server. + product.name is immutable. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask paths include ``product_labels``, ``display_name``, + and ``description``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product, update_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.UpdateProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.UpdateProductRequest): + request = product_search_service.UpdateProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product.name", request.product.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_product(self, + request: Optional[Union[product_search_service.DeleteProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a product and its reference images. + + Metadata of the product and all its images will be deleted right + away, but search queries against ProductSets containing the + product may still work until all related caches are refreshed. + + Possible errors: + + - Returns NOT_FOUND if the product does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_delete_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.DeleteProductRequest, dict]): + The request object. Request message for the ``DeleteProduct`` method. + name (str): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteProductRequest): + request = product_search_service.DeleteProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def create_reference_image(self, + request: Optional[Union[product_search_service.CreateReferenceImageRequest, dict]] = None, + *, + parent: Optional[str] = None, + reference_image: Optional[product_search_service.ReferenceImage] = None, + reference_image_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_create_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + reference_image = vision_v1p3beta1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1p3beta1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = client.create_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.CreateReferenceImageRequest, dict]): + The request object. Request message for the ``CreateReferenceImage`` method. + parent (str): + Required. Resource name of the product in which to + create the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image (google.cloud.vision_v1p3beta1.types.ReferenceImage): + Required. The reference image to + create. If an image ID is specified, it + is ignored. + + This corresponds to the ``reference_image`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image_id (str): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value + as the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``reference_image_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, reference_image, reference_image_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateReferenceImageRequest): + request = product_search_service.CreateReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if reference_image is not None: + request.reference_image = reference_image + if reference_image_id is not None: + request.reference_image_id = reference_image_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_reference_image(self, + request: Optional[Union[product_search_service.DeleteReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a reference image. + + The image metadata will be deleted right away, but search + queries against ProductSets containing the image may still work + until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + Possible errors: + + - Returns NOT_FOUND if the reference image does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_delete_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + client.delete_reference_image(request=request) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.DeleteReferenceImageRequest, dict]): + The request object. Request message for the ``DeleteReferenceImage`` method. + name (str): + Required. The resource name of the reference image to + delete. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteReferenceImageRequest): + request = product_search_service.DeleteReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def list_reference_images(self, + request: Optional[Union[product_search_service.ListReferenceImagesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListReferenceImagesPager: + r"""Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_list_reference_images(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.ListReferenceImagesRequest, dict]): + The request object. Request message for the ``ListReferenceImages`` method. + parent (str): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.services.product_search.pagers.ListReferenceImagesPager: + Response message for the ListReferenceImages method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListReferenceImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListReferenceImagesRequest): + request = product_search_service.ListReferenceImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_reference_images] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListReferenceImagesPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_reference_image(self, + request: Optional[Union[product_search_service.GetReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_get_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = client.get_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.GetReferenceImageRequest, dict]): + The request object. Request message for the ``GetReferenceImage`` method. + name (str): + Required. The resource name of the ReferenceImage to + get. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetReferenceImageRequest): + request = product_search_service.GetReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_product_to_product_set(self, + request: Optional[Union[product_search_service.AddProductToProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_add_product_to_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.add_product_to_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.AddProductToProductSetRequest, dict]): + The request object. Request message for the ``AddProductToProductSet`` + method. + name (str): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (str): + Required. The resource name for the Product to be added + to this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.AddProductToProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.AddProductToProductSetRequest): + request = product_search_service.AddProductToProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_product_to_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def remove_product_from_product_set(self, + request: Optional[Union[product_search_service.RemoveProductFromProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Removes a Product from the specified ProductSet. + + Possible errors: + + - Returns NOT_FOUND If the Product is not found under the + ProductSet. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.remove_product_from_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.RemoveProductFromProductSetRequest, dict]): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + name (str): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (str): + Required. The resource name for the Product to be + removed from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.RemoveProductFromProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.RemoveProductFromProductSetRequest): + request = product_search_service.RemoveProductFromProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_product_from_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def list_products_in_product_set(self, + request: Optional[Union[product_search_service.ListProductsInProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsInProductSetPager: + r"""Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_list_products_in_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.ListProductsInProductSetRequest, dict]): + The request object. Request message for the ``ListProductsInProductSet`` + method. + name (str): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductsInProductSetPager: + Response message for the ListProductsInProductSet + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductsInProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductsInProductSetRequest): + request = product_search_service.ListProductsInProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_products_in_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductsInProductSetPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def import_product_sets(self, + request: Optional[Union[product_search_service.ImportProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + input_config: Optional[product_search_service.ImportProductSetsInputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p3beta1 + + def sample_import_product_sets(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p3beta1.types.ImportProductSetsRequest, dict]): + The request object. Request message for the ``ImportProductSets`` method. + parent (str): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + input_config (google.cloud.vision_v1p3beta1.types.ImportProductSetsInputConfig): + Required. The input content for the + list of requests. + + This corresponds to the ``input_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p3beta1.types.ImportProductSetsResponse` + Response message for the ImportProductSets method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, input_config]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ImportProductSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ImportProductSetsRequest): + request = product_search_service.ImportProductSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if input_config is not None: + request.input_config = input_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_product_sets] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + product_search_service.ImportProductSetsResponse, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ProductSearchClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductSearchClient", +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/pagers.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/pagers.py new file mode 100644 index 00000000..ca82409e --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/pagers.py @@ -0,0 +1,502 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator + +from google.cloud.vision_v1p3beta1.types import product_search_service + + +class ListProductSetsPager: + """A pager for iterating through ``list_product_sets`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p3beta1.types.ListProductSetsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``product_sets`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProductSets`` requests and continue to iterate + through the ``product_sets`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p3beta1.types.ListProductSetsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductSetsResponse], + request: product_search_service.ListProductSetsRequest, + response: product_search_service.ListProductSetsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p3beta1.types.ListProductSetsRequest): + The initial request object. + response (google.cloud.vision_v1p3beta1.types.ListProductSetsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductSetsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductSetsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.ProductSet]: + for page in self.pages: + yield from page.product_sets + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductSetsAsyncPager: + """A pager for iterating through ``list_product_sets`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p3beta1.types.ListProductSetsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``product_sets`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProductSets`` requests and continue to iterate + through the ``product_sets`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p3beta1.types.ListProductSetsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductSetsResponse]], + request: product_search_service.ListProductSetsRequest, + response: product_search_service.ListProductSetsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p3beta1.types.ListProductSetsRequest): + The initial request object. + response (google.cloud.vision_v1p3beta1.types.ListProductSetsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductSetsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductSetsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.ProductSet]: + async def async_generator(): + async for page in self.pages: + for response in page.product_sets: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p3beta1.types.ListProductsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProducts`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p3beta1.types.ListProductsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductsResponse], + request: product_search_service.ListProductsRequest, + response: product_search_service.ListProductsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p3beta1.types.ListProductsRequest): + The initial request object. + response (google.cloud.vision_v1p3beta1.types.ListProductsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.Product]: + for page in self.pages: + yield from page.products + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsAsyncPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p3beta1.types.ListProductsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProducts`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p3beta1.types.ListProductsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductsResponse]], + request: product_search_service.ListProductsRequest, + response: product_search_service.ListProductsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p3beta1.types.ListProductsRequest): + The initial request object. + response (google.cloud.vision_v1p3beta1.types.ListProductsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.Product]: + async def async_generator(): + async for page in self.pages: + for response in page.products: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListReferenceImagesPager: + """A pager for iterating through ``list_reference_images`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p3beta1.types.ListReferenceImagesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``reference_images`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListReferenceImages`` requests and continue to iterate + through the ``reference_images`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p3beta1.types.ListReferenceImagesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListReferenceImagesResponse], + request: product_search_service.ListReferenceImagesRequest, + response: product_search_service.ListReferenceImagesResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p3beta1.types.ListReferenceImagesRequest): + The initial request object. + response (google.cloud.vision_v1p3beta1.types.ListReferenceImagesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListReferenceImagesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListReferenceImagesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.ReferenceImage]: + for page in self.pages: + yield from page.reference_images + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListReferenceImagesAsyncPager: + """A pager for iterating through ``list_reference_images`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p3beta1.types.ListReferenceImagesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``reference_images`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListReferenceImages`` requests and continue to iterate + through the ``reference_images`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p3beta1.types.ListReferenceImagesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListReferenceImagesResponse]], + request: product_search_service.ListReferenceImagesRequest, + response: product_search_service.ListReferenceImagesResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p3beta1.types.ListReferenceImagesRequest): + The initial request object. + response (google.cloud.vision_v1p3beta1.types.ListReferenceImagesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListReferenceImagesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListReferenceImagesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.ReferenceImage]: + async def async_generator(): + async for page in self.pages: + for response in page.reference_images: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsInProductSetPager: + """A pager for iterating through ``list_products_in_product_set`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p3beta1.types.ListProductsInProductSetResponse` object, and + provides an ``__iter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProductsInProductSet`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p3beta1.types.ListProductsInProductSetResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductsInProductSetResponse], + request: product_search_service.ListProductsInProductSetRequest, + response: product_search_service.ListProductsInProductSetResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p3beta1.types.ListProductsInProductSetRequest): + The initial request object. + response (google.cloud.vision_v1p3beta1.types.ListProductsInProductSetResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsInProductSetRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductsInProductSetResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.Product]: + for page in self.pages: + yield from page.products + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsInProductSetAsyncPager: + """A pager for iterating through ``list_products_in_product_set`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p3beta1.types.ListProductsInProductSetResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProductsInProductSet`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p3beta1.types.ListProductsInProductSetResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductsInProductSetResponse]], + request: product_search_service.ListProductsInProductSetRequest, + response: product_search_service.ListProductsInProductSetResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p3beta1.types.ListProductsInProductSetRequest): + The initial request object. + response (google.cloud.vision_v1p3beta1.types.ListProductsInProductSetResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsInProductSetRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductsInProductSetResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.Product]: + async def async_generator(): + async for page in self.pages: + for response in page.products: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/__init__.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/__init__.py new file mode 100644 index 00000000..eb2b97bb --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +from typing import Dict, Type + +from .base import ProductSearchTransport +from .grpc import ProductSearchGrpcTransport +from .grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .rest import ProductSearchRestTransport +from .rest import ProductSearchRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ProductSearchTransport]] +_transport_registry['grpc'] = ProductSearchGrpcTransport +_transport_registry['grpc_asyncio'] = ProductSearchGrpcAsyncIOTransport +_transport_registry['rest'] = ProductSearchRestTransport + +__all__ = ( + 'ProductSearchTransport', + 'ProductSearchGrpcTransport', + 'ProductSearchGrpcAsyncIOTransport', + 'ProductSearchRestTransport', + 'ProductSearchRestInterceptor', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/base.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/base.py new file mode 100644 index 00000000..b626018a --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/base.py @@ -0,0 +1,505 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.vision_v1p3beta1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.vision_v1p3beta1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ProductSearchTransport(abc.ABC): + """Abstract transport class for ProductSearch.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', + ) + + DEFAULT_HOST: str = 'vision.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience(api_audience if api_audience else host) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_product_set: gapic_v1.method.wrap_method( + self.create_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_product_sets: gapic_v1.method.wrap_method( + self.list_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_product_set: gapic_v1.method.wrap_method( + self.get_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.update_product_set: gapic_v1.method.wrap_method( + self.update_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_product_set: gapic_v1.method.wrap_method( + self.delete_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.create_product: gapic_v1.method.wrap_method( + self.create_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_products: gapic_v1.method.wrap_method( + self.list_products, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_product: gapic_v1.method.wrap_method( + self.get_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.update_product: gapic_v1.method.wrap_method( + self.update_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_product: gapic_v1.method.wrap_method( + self.delete_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.create_reference_image: gapic_v1.method.wrap_method( + self.create_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_reference_image: gapic_v1.method.wrap_method( + self.delete_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_reference_images: gapic_v1.method.wrap_method( + self.list_reference_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_reference_image: gapic_v1.method.wrap_method( + self.get_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.add_product_to_product_set: gapic_v1.method.wrap_method( + self.add_product_to_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.remove_product_from_product_set: gapic_v1.method.wrap_method( + self.remove_product_from_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_products_in_product_set: gapic_v1.method.wrap_method( + self.list_products_in_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.import_product_sets: gapic_v1.method.wrap_method( + self.import_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + Union[ + product_search_service.ListProductSetsResponse, + Awaitable[product_search_service.ListProductSetsResponse] + ]]: + raise NotImplementedError() + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + Union[ + product_search_service.ListProductsResponse, + Awaitable[product_search_service.ListProductsResponse] + ]]: + raise NotImplementedError() + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + Union[ + product_search_service.ReferenceImage, + Awaitable[product_search_service.ReferenceImage] + ]]: + raise NotImplementedError() + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + Union[ + product_search_service.ListReferenceImagesResponse, + Awaitable[product_search_service.ListReferenceImagesResponse] + ]]: + raise NotImplementedError() + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + Union[ + product_search_service.ReferenceImage, + Awaitable[product_search_service.ReferenceImage] + ]]: + raise NotImplementedError() + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + Union[ + product_search_service.ListProductsInProductSetResponse, + Awaitable[product_search_service.ListProductsInProductSetResponse] + ]]: + raise NotImplementedError() + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ProductSearchTransport', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/grpc.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/grpc.py new file mode 100644 index 00000000..888536a1 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/grpc.py @@ -0,0 +1,890 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.vision_v1p3beta1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO + + +class ProductSearchGrpcTransport(ProductSearchTransport): + """gRPC backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p3beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p3beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the create product set method over gRPC. + + Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + Returns: + Callable[[~.CreateProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product_set' not in self._stubs: + self._stubs['create_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/CreateProductSet', + request_serializer=product_search_service.CreateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['create_product_set'] + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + product_search_service.ListProductSetsResponse]: + r"""Return a callable for the list product sets method over gRPC. + + Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + Returns: + Callable[[~.ListProductSetsRequest], + ~.ListProductSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_product_sets' not in self._stubs: + self._stubs['list_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ListProductSets', + request_serializer=product_search_service.ListProductSetsRequest.serialize, + response_deserializer=product_search_service.ListProductSetsResponse.deserialize, + ) + return self._stubs['list_product_sets'] + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the get product set method over gRPC. + + Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + Returns: + Callable[[~.GetProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product_set' not in self._stubs: + self._stubs['get_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/GetProductSet', + request_serializer=product_search_service.GetProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['get_product_set'] + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the update product set method over gRPC. + + Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + Returns: + Callable[[~.UpdateProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product_set' not in self._stubs: + self._stubs['update_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/UpdateProductSet', + request_serializer=product_search_service.UpdateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['update_product_set'] + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product set method over gRPC. + + Permanently deletes a ProductSet. All Products and + ReferenceImages in the ProductSet will be deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + Returns: + Callable[[~.DeleteProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product_set' not in self._stubs: + self._stubs['delete_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/DeleteProductSet', + request_serializer=product_search_service.DeleteProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product_set'] + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + product_search_service.Product]: + r"""Return a callable for the create product method over gRPC. + + Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + Returns: + Callable[[~.CreateProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product' not in self._stubs: + self._stubs['create_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/CreateProduct', + request_serializer=product_search_service.CreateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + product_search_service.ListProductsResponse]: + r"""Return a callable for the list products method over gRPC. + + Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsRequest], + ~.ListProductsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products' not in self._stubs: + self._stubs['list_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ListProducts', + request_serializer=product_search_service.ListProductsRequest.serialize, + response_deserializer=product_search_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + product_search_service.Product]: + r"""Return a callable for the get product method over gRPC. + + Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + Returns: + Callable[[~.GetProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product' not in self._stubs: + self._stubs['get_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/GetProduct', + request_serializer=product_search_service.GetProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + product_search_service.Product]: + r"""Return a callable for the update product method over gRPC. + + Makes changes to a Product resource. Only display_name, + description and labels can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + Returns: + Callable[[~.UpdateProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product' not in self._stubs: + self._stubs['update_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/UpdateProduct', + request_serializer=product_search_service.UpdateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product method over gRPC. + + Permanently deletes a product and its reference images. + + Metadata of the product and all its images will be deleted right + away, but search queries against ProductSets containing the + product may still work until all related caches are refreshed. + + Possible errors: + + - Returns NOT_FOUND if the product does not exist. + + Returns: + Callable[[~.DeleteProductRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product' not in self._stubs: + self._stubs['delete_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/DeleteProduct', + request_serializer=product_search_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + product_search_service.ReferenceImage]: + r"""Return a callable for the create reference image method over gRPC. + + Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + Returns: + Callable[[~.CreateReferenceImageRequest], + ~.ReferenceImage]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_reference_image' not in self._stubs: + self._stubs['create_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/CreateReferenceImage', + request_serializer=product_search_service.CreateReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['create_reference_image'] + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete reference image method over gRPC. + + Permanently deletes a reference image. + + The image metadata will be deleted right away, but search + queries against ProductSets containing the image may still work + until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + Possible errors: + + - Returns NOT_FOUND if the reference image does not exist. + + Returns: + Callable[[~.DeleteReferenceImageRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_reference_image' not in self._stubs: + self._stubs['delete_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/DeleteReferenceImage', + request_serializer=product_search_service.DeleteReferenceImageRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_reference_image'] + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + product_search_service.ListReferenceImagesResponse]: + r"""Return a callable for the list reference images method over gRPC. + + Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + Returns: + Callable[[~.ListReferenceImagesRequest], + ~.ListReferenceImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_reference_images' not in self._stubs: + self._stubs['list_reference_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ListReferenceImages', + request_serializer=product_search_service.ListReferenceImagesRequest.serialize, + response_deserializer=product_search_service.ListReferenceImagesResponse.deserialize, + ) + return self._stubs['list_reference_images'] + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + product_search_service.ReferenceImage]: + r"""Return a callable for the get reference image method over gRPC. + + Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + Returns: + Callable[[~.GetReferenceImageRequest], + ~.ReferenceImage]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_reference_image' not in self._stubs: + self._stubs['get_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/GetReferenceImage', + request_serializer=product_search_service.GetReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['get_reference_image'] + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the add product to product set method over gRPC. + + Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + Returns: + Callable[[~.AddProductToProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'add_product_to_product_set' not in self._stubs: + self._stubs['add_product_to_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/AddProductToProductSet', + request_serializer=product_search_service.AddProductToProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['add_product_to_product_set'] + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the remove product from product + set method over gRPC. + + Removes a Product from the specified ProductSet. + + Possible errors: + + - Returns NOT_FOUND If the Product is not found under the + ProductSet. + + Returns: + Callable[[~.RemoveProductFromProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'remove_product_from_product_set' not in self._stubs: + self._stubs['remove_product_from_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/RemoveProductFromProductSet', + request_serializer=product_search_service.RemoveProductFromProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['remove_product_from_product_set'] + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + product_search_service.ListProductsInProductSetResponse]: + r"""Return a callable for the list products in product set method over gRPC. + + Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsInProductSetRequest], + ~.ListProductsInProductSetResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products_in_product_set' not in self._stubs: + self._stubs['list_products_in_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ListProductsInProductSet', + request_serializer=product_search_service.ListProductsInProductSetRequest.serialize, + response_deserializer=product_search_service.ListProductsInProductSetResponse.deserialize, + ) + return self._stubs['list_products_in_product_set'] + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import product sets method over gRPC. + + Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri]. + + Returns: + Callable[[~.ImportProductSetsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'import_product_sets' not in self._stubs: + self._stubs['import_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ImportProductSets', + request_serializer=product_search_service.ImportProductSetsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_product_sets'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ProductSearchGrpcTransport', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/grpc_asyncio.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/grpc_asyncio.py new file mode 100644 index 00000000..9656d898 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/grpc_asyncio.py @@ -0,0 +1,889 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.vision_v1p3beta1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .grpc import ProductSearchGrpcTransport + + +class ProductSearchGrpcAsyncIOTransport(ProductSearchTransport): + """gRPC AsyncIO backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p3beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p3beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the create product set method over gRPC. + + Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + Returns: + Callable[[~.CreateProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product_set' not in self._stubs: + self._stubs['create_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/CreateProductSet', + request_serializer=product_search_service.CreateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['create_product_set'] + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + Awaitable[product_search_service.ListProductSetsResponse]]: + r"""Return a callable for the list product sets method over gRPC. + + Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + Returns: + Callable[[~.ListProductSetsRequest], + Awaitable[~.ListProductSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_product_sets' not in self._stubs: + self._stubs['list_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ListProductSets', + request_serializer=product_search_service.ListProductSetsRequest.serialize, + response_deserializer=product_search_service.ListProductSetsResponse.deserialize, + ) + return self._stubs['list_product_sets'] + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the get product set method over gRPC. + + Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + Returns: + Callable[[~.GetProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product_set' not in self._stubs: + self._stubs['get_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/GetProductSet', + request_serializer=product_search_service.GetProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['get_product_set'] + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the update product set method over gRPC. + + Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + Returns: + Callable[[~.UpdateProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product_set' not in self._stubs: + self._stubs['update_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/UpdateProductSet', + request_serializer=product_search_service.UpdateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['update_product_set'] + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product set method over gRPC. + + Permanently deletes a ProductSet. All Products and + ReferenceImages in the ProductSet will be deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + Returns: + Callable[[~.DeleteProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product_set' not in self._stubs: + self._stubs['delete_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/DeleteProductSet', + request_serializer=product_search_service.DeleteProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product_set'] + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the create product method over gRPC. + + Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + Returns: + Callable[[~.CreateProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product' not in self._stubs: + self._stubs['create_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/CreateProduct', + request_serializer=product_search_service.CreateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + Awaitable[product_search_service.ListProductsResponse]]: + r"""Return a callable for the list products method over gRPC. + + Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsRequest], + Awaitable[~.ListProductsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products' not in self._stubs: + self._stubs['list_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ListProducts', + request_serializer=product_search_service.ListProductsRequest.serialize, + response_deserializer=product_search_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the get product method over gRPC. + + Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + Returns: + Callable[[~.GetProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product' not in self._stubs: + self._stubs['get_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/GetProduct', + request_serializer=product_search_service.GetProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the update product method over gRPC. + + Makes changes to a Product resource. Only display_name, + description and labels can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + Returns: + Callable[[~.UpdateProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product' not in self._stubs: + self._stubs['update_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/UpdateProduct', + request_serializer=product_search_service.UpdateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product method over gRPC. + + Permanently deletes a product and its reference images. + + Metadata of the product and all its images will be deleted right + away, but search queries against ProductSets containing the + product may still work until all related caches are refreshed. + + Possible errors: + + - Returns NOT_FOUND if the product does not exist. + + Returns: + Callable[[~.DeleteProductRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product' not in self._stubs: + self._stubs['delete_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/DeleteProduct', + request_serializer=product_search_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + Awaitable[product_search_service.ReferenceImage]]: + r"""Return a callable for the create reference image method over gRPC. + + Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + Returns: + Callable[[~.CreateReferenceImageRequest], + Awaitable[~.ReferenceImage]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_reference_image' not in self._stubs: + self._stubs['create_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/CreateReferenceImage', + request_serializer=product_search_service.CreateReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['create_reference_image'] + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete reference image method over gRPC. + + Permanently deletes a reference image. + + The image metadata will be deleted right away, but search + queries against ProductSets containing the image may still work + until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + Possible errors: + + - Returns NOT_FOUND if the reference image does not exist. + + Returns: + Callable[[~.DeleteReferenceImageRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_reference_image' not in self._stubs: + self._stubs['delete_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/DeleteReferenceImage', + request_serializer=product_search_service.DeleteReferenceImageRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_reference_image'] + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + Awaitable[product_search_service.ListReferenceImagesResponse]]: + r"""Return a callable for the list reference images method over gRPC. + + Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + Returns: + Callable[[~.ListReferenceImagesRequest], + Awaitable[~.ListReferenceImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_reference_images' not in self._stubs: + self._stubs['list_reference_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ListReferenceImages', + request_serializer=product_search_service.ListReferenceImagesRequest.serialize, + response_deserializer=product_search_service.ListReferenceImagesResponse.deserialize, + ) + return self._stubs['list_reference_images'] + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + Awaitable[product_search_service.ReferenceImage]]: + r"""Return a callable for the get reference image method over gRPC. + + Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + Returns: + Callable[[~.GetReferenceImageRequest], + Awaitable[~.ReferenceImage]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_reference_image' not in self._stubs: + self._stubs['get_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/GetReferenceImage', + request_serializer=product_search_service.GetReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['get_reference_image'] + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the add product to product set method over gRPC. + + Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + Returns: + Callable[[~.AddProductToProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'add_product_to_product_set' not in self._stubs: + self._stubs['add_product_to_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/AddProductToProductSet', + request_serializer=product_search_service.AddProductToProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['add_product_to_product_set'] + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the remove product from product + set method over gRPC. + + Removes a Product from the specified ProductSet. + + Possible errors: + + - Returns NOT_FOUND If the Product is not found under the + ProductSet. + + Returns: + Callable[[~.RemoveProductFromProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'remove_product_from_product_set' not in self._stubs: + self._stubs['remove_product_from_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/RemoveProductFromProductSet', + request_serializer=product_search_service.RemoveProductFromProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['remove_product_from_product_set'] + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + Awaitable[product_search_service.ListProductsInProductSetResponse]]: + r"""Return a callable for the list products in product set method over gRPC. + + Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsInProductSetRequest], + Awaitable[~.ListProductsInProductSetResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products_in_product_set' not in self._stubs: + self._stubs['list_products_in_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ListProductsInProductSet', + request_serializer=product_search_service.ListProductsInProductSetRequest.serialize, + response_deserializer=product_search_service.ListProductsInProductSetResponse.deserialize, + ) + return self._stubs['list_products_in_product_set'] + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import product sets method over gRPC. + + Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p3beta1.ImportProductSetsGcsSource.csv_file_uri]. + + Returns: + Callable[[~.ImportProductSetsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'import_product_sets' not in self._stubs: + self._stubs['import_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p3beta1.ProductSearch/ImportProductSets', + request_serializer=product_search_service.ImportProductSetsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_product_sets'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ProductSearchGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/rest.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/rest.py new file mode 100644 index 00000000..0503ab43 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/services/product_search/transports/rest.py @@ -0,0 +1,2186 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.auth.transport.requests import AuthorizedSession # type: ignore +import json # type: ignore +import grpc # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.api_core import rest_helpers +from google.api_core import rest_streaming +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from google.api_core import operations_v1 +from requests import __version__ as requests_version +import dataclasses +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.cloud.vision_v1p3beta1.types import product_search_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ProductSearchRestInterceptor: + """Interceptor for ProductSearch. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ProductSearchRestTransport. + + .. code-block:: python + class MyCustomProductSearchInterceptor(ProductSearchRestInterceptor): + def pre_add_product_to_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_create_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_reference_image(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_reference_image(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_product_sets(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_product_sets(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_products(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_products(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_product_sets(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_product_sets(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_products_in_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_products_in_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_reference_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_reference_images(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_product_from_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_update_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ProductSearchRestTransport(interceptor=MyCustomProductSearchInterceptor()) + client = ProductSearchClient(transport=transport) + + + """ + def pre_add_product_to_product_set(self, request: product_search_service.AddProductToProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.AddProductToProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_product_to_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_create_product(self, request: product_search_service.CreateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for create_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_create_product_set(self, request: product_search_service.CreateProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for create_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_create_reference_image(self, request: product_search_service.CreateReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_reference_image(self, response: product_search_service.ReferenceImage) -> product_search_service.ReferenceImage: + """Post-rpc interceptor for create_reference_image + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_delete_product(self, request: product_search_service.DeleteProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_delete_product_set(self, request: product_search_service.DeleteProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_delete_reference_image(self, request: product_search_service.DeleteReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_get_product(self, request: product_search_service.GetProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for get_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_get_product_set(self, request: product_search_service.GetProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for get_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_get_reference_image(self, request: product_search_service.GetReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_reference_image(self, response: product_search_service.ReferenceImage) -> product_search_service.ReferenceImage: + """Post-rpc interceptor for get_reference_image + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_import_product_sets(self, request: product_search_service.ImportProductSetsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ImportProductSetsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_product_sets + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_import_product_sets(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_product_sets + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_products(self, request: product_search_service.ListProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_products + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_products(self, response: product_search_service.ListProductsResponse) -> product_search_service.ListProductsResponse: + """Post-rpc interceptor for list_products + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_product_sets(self, request: product_search_service.ListProductSetsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductSetsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_product_sets + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_product_sets(self, response: product_search_service.ListProductSetsResponse) -> product_search_service.ListProductSetsResponse: + """Post-rpc interceptor for list_product_sets + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_products_in_product_set(self, request: product_search_service.ListProductsInProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductsInProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_products_in_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_products_in_product_set(self, response: product_search_service.ListProductsInProductSetResponse) -> product_search_service.ListProductsInProductSetResponse: + """Post-rpc interceptor for list_products_in_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_reference_images(self, request: product_search_service.ListReferenceImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListReferenceImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_reference_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_reference_images(self, response: product_search_service.ListReferenceImagesResponse) -> product_search_service.ListReferenceImagesResponse: + """Post-rpc interceptor for list_reference_images + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_remove_product_from_product_set(self, request: product_search_service.RemoveProductFromProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.RemoveProductFromProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_product_from_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_update_product(self, request: product_search_service.UpdateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.UpdateProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_update_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for update_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_update_product_set(self, request: product_search_service.UpdateProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.UpdateProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_update_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for update_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ProductSearchRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ProductSearchRestInterceptor + + +class ProductSearchRestTransport(ProductSearchTransport): + """REST backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p3beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p3beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p3beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[ + ], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + interceptor: Optional[ProductSearchRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError(f"Unexpected hostname structure: {host}") # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ProductSearchRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1p3beta1") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AddProductToProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("AddProductToProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.AddProductToProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the add product to product + set method over HTTP. + + Args: + request (~.product_search_service.AddProductToProductSetRequest): + The request object. Request message for the ``AddProductToProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/productSets/*}:addProduct', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_product_to_product_set(request, metadata) + pb_request = product_search_service.AddProductToProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _CreateProduct(ProductSearchRestStub): + def __hash__(self): + return hash("CreateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the create product method over HTTP. + + Args: + request (~.product_search_service.CreateProductRequest): + The request object. Request message for the ``CreateProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p3beta1/{parent=projects/*/locations/*}/products', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_create_product(request, metadata) + pb_request = product_search_service.CreateProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product(resp) + return resp + + class _CreateProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("CreateProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the create product set method over HTTP. + + Args: + request (~.product_search_service.CreateProductSetRequest): + The request object. Request message for the ``CreateProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p3beta1/{parent=projects/*/locations/*}/productSets', + 'body': 'product_set', + }, + ] + request, metadata = self._interceptor.pre_create_product_set(request, metadata) + pb_request = product_search_service.CreateProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product_set(resp) + return resp + + class _CreateReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("CreateReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ReferenceImage: + r"""Call the create reference image method over HTTP. + + Args: + request (~.product_search_service.CreateReferenceImageRequest): + The request object. Request message for the ``CreateReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ReferenceImage: + A ``ReferenceImage`` represents a product image and its + associated metadata, such as bounding boxes. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages', + 'body': 'reference_image', + }, + ] + request, metadata = self._interceptor.pre_create_reference_image(request, metadata) + pb_request = product_search_service.CreateReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ReferenceImage() + pb_resp = product_search_service.ReferenceImage.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_reference_image(resp) + return resp + + class _DeleteProduct(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete product method over HTTP. + + Args: + request (~.product_search_service.DeleteProductRequest): + The request object. Request message for the ``DeleteProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/products/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_product(request, metadata) + pb_request = product_search_service.DeleteProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete product set method over HTTP. + + Args: + request (~.product_search_service.DeleteProductSetRequest): + The request object. Request message for the ``DeleteProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/productSets/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_product_set(request, metadata) + pb_request = product_search_service.DeleteProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete reference image method over HTTP. + + Args: + request (~.product_search_service.DeleteReferenceImageRequest): + The request object. Request message for the ``DeleteReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_reference_image(request, metadata) + pb_request = product_search_service.DeleteReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _GetProduct(ProductSearchRestStub): + def __hash__(self): + return hash("GetProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the get product method over HTTP. + + Args: + request (~.product_search_service.GetProductRequest): + The request object. Request message for the ``GetProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/products/*}', + }, + ] + request, metadata = self._interceptor.pre_get_product(request, metadata) + pb_request = product_search_service.GetProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product(resp) + return resp + + class _GetProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("GetProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the get product set method over HTTP. + + Args: + request (~.product_search_service.GetProductSetRequest): + The request object. Request message for the ``GetProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/productSets/*}', + }, + ] + request, metadata = self._interceptor.pre_get_product_set(request, metadata) + pb_request = product_search_service.GetProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product_set(resp) + return resp + + class _GetReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("GetReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ReferenceImage: + r"""Call the get reference image method over HTTP. + + Args: + request (~.product_search_service.GetReferenceImageRequest): + The request object. Request message for the ``GetReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ReferenceImage: + A ``ReferenceImage`` represents a product image and its + associated metadata, such as bounding boxes. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}', + }, + ] + request, metadata = self._interceptor.pre_get_reference_image(request, metadata) + pb_request = product_search_service.GetReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ReferenceImage() + pb_resp = product_search_service.ReferenceImage.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_reference_image(resp) + return resp + + class _ImportProductSets(ProductSearchRestStub): + def __hash__(self): + return hash("ImportProductSets") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ImportProductSetsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import product sets method over HTTP. + + Args: + request (~.product_search_service.ImportProductSetsRequest): + The request object. Request message for the ``ImportProductSets`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p3beta1/{parent=projects/*/locations/*}/productSets:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_product_sets(request, metadata) + pb_request = product_search_service.ImportProductSetsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_import_product_sets(resp) + return resp + + class _ListProducts(ProductSearchRestStub): + def __hash__(self): + return hash("ListProducts") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductsResponse: + r"""Call the list products method over HTTP. + + Args: + request (~.product_search_service.ListProductsRequest): + The request object. Request message for the ``ListProducts`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductsResponse: + Response message for the ``ListProducts`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p3beta1/{parent=projects/*/locations/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products(request, metadata) + pb_request = product_search_service.ListProductsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductsResponse() + pb_resp = product_search_service.ListProductsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_products(resp) + return resp + + class _ListProductSets(ProductSearchRestStub): + def __hash__(self): + return hash("ListProductSets") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductSetsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductSetsResponse: + r"""Call the list product sets method over HTTP. + + Args: + request (~.product_search_service.ListProductSetsRequest): + The request object. Request message for the ``ListProductSets`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductSetsResponse: + Response message for the ``ListProductSets`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p3beta1/{parent=projects/*/locations/*}/productSets', + }, + ] + request, metadata = self._interceptor.pre_list_product_sets(request, metadata) + pb_request = product_search_service.ListProductSetsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductSetsResponse() + pb_resp = product_search_service.ListProductSetsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_product_sets(resp) + return resp + + class _ListProductsInProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("ListProductsInProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductsInProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductsInProductSetResponse: + r"""Call the list products in product + set method over HTTP. + + Args: + request (~.product_search_service.ListProductsInProductSetRequest): + The request object. Request message for the ``ListProductsInProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductsInProductSetResponse: + Response message for the ``ListProductsInProductSet`` + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/productSets/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products_in_product_set(request, metadata) + pb_request = product_search_service.ListProductsInProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductsInProductSetResponse() + pb_resp = product_search_service.ListProductsInProductSetResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_products_in_product_set(resp) + return resp + + class _ListReferenceImages(ProductSearchRestStub): + def __hash__(self): + return hash("ListReferenceImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListReferenceImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListReferenceImagesResponse: + r"""Call the list reference images method over HTTP. + + Args: + request (~.product_search_service.ListReferenceImagesRequest): + The request object. Request message for the ``ListReferenceImages`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListReferenceImagesResponse: + Response message for the ``ListReferenceImages`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages', + }, + ] + request, metadata = self._interceptor.pre_list_reference_images(request, metadata) + pb_request = product_search_service.ListReferenceImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListReferenceImagesResponse() + pb_resp = product_search_service.ListReferenceImagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_reference_images(resp) + return resp + + class _RemoveProductFromProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("RemoveProductFromProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.RemoveProductFromProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the remove product from + product set method over HTTP. + + Args: + request (~.product_search_service.RemoveProductFromProductSetRequest): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p3beta1/{name=projects/*/locations/*/productSets/*}:removeProduct', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_product_from_product_set(request, metadata) + pb_request = product_search_service.RemoveProductFromProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _UpdateProduct(ProductSearchRestStub): + def __hash__(self): + return hash("UpdateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.UpdateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the update product method over HTTP. + + Args: + request (~.product_search_service.UpdateProductRequest): + The request object. Request message for the ``UpdateProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v1p3beta1/{product.name=projects/*/locations/*/products/*}', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_update_product(request, metadata) + pb_request = product_search_service.UpdateProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product(resp) + return resp + + class _UpdateProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("UpdateProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.UpdateProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the update product set method over HTTP. + + Args: + request (~.product_search_service.UpdateProductSetRequest): + The request object. Request message for the ``UpdateProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v1p3beta1/{product_set.name=projects/*/locations/*/productSets/*}', + 'body': 'product_set', + }, + ] + request, metadata = self._interceptor.pre_update_product_set(request, metadata) + pb_request = product_search_service.UpdateProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product_set(resp) + return resp + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AddProductToProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + product_search_service.ReferenceImage]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + product_search_service.ReferenceImage]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ImportProductSets(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + product_search_service.ListProductsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProducts(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + product_search_service.ListProductSetsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProductSets(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + product_search_service.ListProductsInProductSetResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProductsInProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + product_search_service.ListReferenceImagesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListReferenceImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._RemoveProductFromProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ProductSearchRestTransport', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/__init__.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/__init__.py new file mode 100644 index 00000000..807fd54a --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/__init__.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .geometry import ( + BoundingPoly, + NormalizedVertex, + Position, + Vertex, +) +from .image_annotator import ( + AnnotateFileResponse, + AnnotateImageRequest, + AnnotateImageResponse, + AsyncAnnotateFileRequest, + AsyncAnnotateFileResponse, + AsyncBatchAnnotateFilesRequest, + AsyncBatchAnnotateFilesResponse, + BatchAnnotateImagesRequest, + BatchAnnotateImagesResponse, + ColorInfo, + CropHint, + CropHintsAnnotation, + CropHintsParams, + DominantColorsAnnotation, + EntityAnnotation, + FaceAnnotation, + Feature, + GcsDestination, + GcsSource, + Image, + ImageAnnotationContext, + ImageContext, + ImageProperties, + ImageSource, + InputConfig, + LatLongRect, + LocalizedObjectAnnotation, + LocationInfo, + OperationMetadata, + OutputConfig, + Property, + SafeSearchAnnotation, + TextDetectionParams, + WebDetectionParams, + Likelihood, +) +from .product_search import ( + ProductSearchParams, + ProductSearchResults, +) +from .product_search_service import ( + AddProductToProductSetRequest, + BatchOperationMetadata, + CreateProductRequest, + CreateProductSetRequest, + CreateReferenceImageRequest, + DeleteProductRequest, + DeleteProductSetRequest, + DeleteReferenceImageRequest, + GetProductRequest, + GetProductSetRequest, + GetReferenceImageRequest, + ImportProductSetsGcsSource, + ImportProductSetsInputConfig, + ImportProductSetsRequest, + ImportProductSetsResponse, + ListProductSetsRequest, + ListProductSetsResponse, + ListProductsInProductSetRequest, + ListProductsInProductSetResponse, + ListProductsRequest, + ListProductsResponse, + ListReferenceImagesRequest, + ListReferenceImagesResponse, + Product, + ProductSet, + ReferenceImage, + RemoveProductFromProductSetRequest, + UpdateProductRequest, + UpdateProductSetRequest, +) +from .text_annotation import ( + Block, + Page, + Paragraph, + Symbol, + TextAnnotation, + Word, +) +from .web_detection import ( + WebDetection, +) + +__all__ = ( + 'BoundingPoly', + 'NormalizedVertex', + 'Position', + 'Vertex', + 'AnnotateFileResponse', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'GcsDestination', + 'GcsSource', + 'Image', + 'ImageAnnotationContext', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'InputConfig', + 'LatLongRect', + 'LocalizedObjectAnnotation', + 'LocationInfo', + 'OperationMetadata', + 'OutputConfig', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'ProductSearchParams', + 'ProductSearchResults', + 'AddProductToProductSetRequest', + 'BatchOperationMetadata', + 'CreateProductRequest', + 'CreateProductSetRequest', + 'CreateReferenceImageRequest', + 'DeleteProductRequest', + 'DeleteProductSetRequest', + 'DeleteReferenceImageRequest', + 'GetProductRequest', + 'GetProductSetRequest', + 'GetReferenceImageRequest', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ListProductsRequest', + 'ListProductsResponse', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'Product', + 'ProductSet', + 'ReferenceImage', + 'RemoveProductFromProductSetRequest', + 'UpdateProductRequest', + 'UpdateProductSetRequest', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/geometry.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/geometry.py new file mode 100644 index 00000000..6174a8bb --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/geometry.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p3beta1', + manifest={ + 'Vertex', + 'NormalizedVertex', + 'BoundingPoly', + 'Position', + }, +) + + +class Vertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the vertex coordinates are in the same scale as the + original image. + + Attributes: + x (int): + X coordinate. + y (int): + Y coordinate. + """ + + x: int = proto.Field( + proto.INT32, + number=1, + ) + y: int = proto.Field( + proto.INT32, + number=2, + ) + + +class NormalizedVertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the normalized vertex coordinates are relative to the + original image and range from 0 to 1. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + + +class BoundingPoly(proto.Message): + r"""A bounding polygon for the detected image annotation. + + Attributes: + vertices (MutableSequence[google.cloud.vision_v1p3beta1.types.Vertex]): + The bounding polygon vertices. + normalized_vertices (MutableSequence[google.cloud.vision_v1p3beta1.types.NormalizedVertex]): + The bounding polygon normalized vertices. + """ + + vertices: MutableSequence['Vertex'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Vertex', + ) + normalized_vertices: MutableSequence['NormalizedVertex'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='NormalizedVertex', + ) + + +class Position(proto.Message): + r"""A 3D position in the image, used primarily for Face detection + landmarks. A valid Position must have both x and y coordinates. + The position coordinates are in the same scale as the original + image. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + z (float): + Z coordinate (or depth). + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + z: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/image_annotator.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/image_annotator.py new file mode 100644 index 00000000..b6be61de --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/image_annotator.py @@ -0,0 +1,1481 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p3beta1.types import geometry +from google.cloud.vision_v1p3beta1.types import product_search +from google.cloud.vision_v1p3beta1.types import text_annotation +from google.cloud.vision_v1p3beta1.types import web_detection as gcv_web_detection +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import latlng_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p3beta1', + manifest={ + 'Likelihood', + 'Feature', + 'ImageSource', + 'Image', + 'FaceAnnotation', + 'LocationInfo', + 'Property', + 'EntityAnnotation', + 'LocalizedObjectAnnotation', + 'SafeSearchAnnotation', + 'LatLongRect', + 'ColorInfo', + 'DominantColorsAnnotation', + 'ImageProperties', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'WebDetectionParams', + 'TextDetectionParams', + 'ImageContext', + 'AnnotateImageRequest', + 'ImageAnnotationContext', + 'AnnotateImageResponse', + 'AnnotateFileResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'InputConfig', + 'OutputConfig', + 'GcsSource', + 'GcsDestination', + 'OperationMetadata', + }, +) + + +class Likelihood(proto.Enum): + r"""A bucketized representation of likelihood, which is intended + to give clients highly stable results across model upgrades. + + Values: + UNKNOWN (0): + Unknown likelihood. + VERY_UNLIKELY (1): + It is very unlikely that the image belongs to + the specified vertical. + UNLIKELY (2): + It is unlikely that the image belongs to the + specified vertical. + POSSIBLE (3): + It is possible that the image belongs to the + specified vertical. + LIKELY (4): + It is likely that the image belongs to the + specified vertical. + VERY_LIKELY (5): + It is very likely that the image belongs to + the specified vertical. + """ + UNKNOWN = 0 + VERY_UNLIKELY = 1 + UNLIKELY = 2 + POSSIBLE = 3 + LIKELY = 4 + VERY_LIKELY = 5 + + +class Feature(proto.Message): + r"""The type of Google Cloud Vision API detection to perform, and the + maximum number of results to return for that type. Multiple + ``Feature`` objects can be specified in the ``features`` list. + + Attributes: + type_ (google.cloud.vision_v1p3beta1.types.Feature.Type): + The feature type. + max_results (int): + Maximum number of results of this type. Does not apply to + ``TEXT_DETECTION``, ``DOCUMENT_TEXT_DETECTION``, or + ``CROP_HINTS``. + model (str): + Model to use for the feature. Supported values: + "builtin/stable" (the default if unset) and + "builtin/latest". ``DOCUMENT_TEXT_DETECTION`` and + ``TEXT_DETECTION`` also support "builtin/weekly" for the + bleeding edge release updated weekly. + """ + class Type(proto.Enum): + r"""Type of Google Cloud Vision API feature to be extracted. + + Values: + TYPE_UNSPECIFIED (0): + Unspecified feature type. + FACE_DETECTION (1): + Run face detection. + LANDMARK_DETECTION (2): + Run landmark detection. + LOGO_DETECTION (3): + Run logo detection. + LABEL_DETECTION (4): + Run label detection. + TEXT_DETECTION (5): + Run text detection / optical character recognition (OCR). + Text detection is optimized for areas of text within a + larger image; if the image is a document, use + ``DOCUMENT_TEXT_DETECTION`` instead. + DOCUMENT_TEXT_DETECTION (11): + Run dense text document OCR. Takes precedence when both + ``DOCUMENT_TEXT_DETECTION`` and ``TEXT_DETECTION`` are + present. + SAFE_SEARCH_DETECTION (6): + Run Safe Search to detect potentially unsafe + or undesirable content. + IMAGE_PROPERTIES (7): + Compute a set of image properties, such as + the image's dominant colors. + CROP_HINTS (9): + Run crop hints. + WEB_DETECTION (10): + Run web detection. + PRODUCT_SEARCH (12): + Run Product Search. + OBJECT_LOCALIZATION (19): + Run localizer for object detection. + """ + TYPE_UNSPECIFIED = 0 + FACE_DETECTION = 1 + LANDMARK_DETECTION = 2 + LOGO_DETECTION = 3 + LABEL_DETECTION = 4 + TEXT_DETECTION = 5 + DOCUMENT_TEXT_DETECTION = 11 + SAFE_SEARCH_DETECTION = 6 + IMAGE_PROPERTIES = 7 + CROP_HINTS = 9 + WEB_DETECTION = 10 + PRODUCT_SEARCH = 12 + OBJECT_LOCALIZATION = 19 + + type_: Type = proto.Field( + proto.ENUM, + number=1, + enum=Type, + ) + max_results: int = proto.Field( + proto.INT32, + number=2, + ) + model: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ImageSource(proto.Message): + r"""External image source (Google Cloud Storage or web URL image + location). + + Attributes: + gcs_image_uri (str): + **Use ``image_uri`` instead.** + + The Google Cloud Storage URI of the form + ``gs://bucket_name/object_name``. Object versioning is not + supported. See `Google Cloud Storage Request + URIs `__ + for more info. + image_uri (str): + The URI of the source image. Can be either: + + 1. A Google Cloud Storage URI of the form + ``gs://bucket_name/object_name``. Object versioning is + not supported. See `Google Cloud Storage Request + URIs `__ + for more info. + + 2. A publicly-accessible image HTTP/HTTPS URL. When fetching + images from HTTP/HTTPS URLs, Google cannot guarantee that + the request will be completed. Your request may fail if + the specified host denies the request (e.g. due to + request throttling or DOS prevention), or if Google + throttles requests to the site for abuse prevention. You + should not depend on externally-hosted images for + production applications. + + When both ``gcs_image_uri`` and ``image_uri`` are specified, + ``image_uri`` takes precedence. + """ + + gcs_image_uri: str = proto.Field( + proto.STRING, + number=1, + ) + image_uri: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Image(proto.Message): + r"""Client image to perform Google Cloud Vision API tasks over. + + Attributes: + content (bytes): + Image content, represented as a stream of bytes. Note: As + with all ``bytes`` fields, protobuffers use a pure binary + representation, whereas JSON representations use base64. + source (google.cloud.vision_v1p3beta1.types.ImageSource): + Google Cloud Storage image location, or publicly-accessible + image URL. If both ``content`` and ``source`` are provided + for an image, ``content`` takes precedence and is used to + perform the image annotation request. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + source: 'ImageSource' = proto.Field( + proto.MESSAGE, + number=2, + message='ImageSource', + ) + + +class FaceAnnotation(proto.Message): + r"""A face annotation object contains the results of face + detection. + + Attributes: + bounding_poly (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The bounding polygon around the face. The coordinates of the + bounding box are in the original image's scale, as returned + in ``ImageParams``. The bounding box is computed to "frame" + the face in accordance with human expectations. It is based + on the landmarker results. Note that one or more x and/or y + coordinates may not be generated in the ``BoundingPoly`` + (the polygon will be unbounded) if only a partial face + appears in the image to be annotated. + fd_bounding_poly (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The ``fd_bounding_poly`` bounding polygon is tighter than + the ``boundingPoly``, and encloses only the skin part of the + face. Typically, it is used to eliminate the face from any + image analysis that detects the "amount of skin" visible in + an image. It is not based on the landmarker results, only on + the initial face detection, hence the fd (face detection) + prefix. + landmarks (MutableSequence[google.cloud.vision_v1p3beta1.types.FaceAnnotation.Landmark]): + Detected face landmarks. + roll_angle (float): + Roll angle, which indicates the amount of + clockwise/anti-clockwise rotation of the face relative to + the image vertical about the axis perpendicular to the face. + Range [-180,180]. + pan_angle (float): + Yaw angle, which indicates the leftward/rightward angle that + the face is pointing relative to the vertical plane + perpendicular to the image. Range [-180,180]. + tilt_angle (float): + Pitch angle, which indicates the upwards/downwards angle + that the face is pointing relative to the image's horizontal + plane. Range [-180,180]. + detection_confidence (float): + Detection confidence. Range [0, 1]. + landmarking_confidence (float): + Face landmarking confidence. Range [0, 1]. + joy_likelihood (google.cloud.vision_v1p3beta1.types.Likelihood): + Joy likelihood. + sorrow_likelihood (google.cloud.vision_v1p3beta1.types.Likelihood): + Sorrow likelihood. + anger_likelihood (google.cloud.vision_v1p3beta1.types.Likelihood): + Anger likelihood. + surprise_likelihood (google.cloud.vision_v1p3beta1.types.Likelihood): + Surprise likelihood. + under_exposed_likelihood (google.cloud.vision_v1p3beta1.types.Likelihood): + Under-exposed likelihood. + blurred_likelihood (google.cloud.vision_v1p3beta1.types.Likelihood): + Blurred likelihood. + headwear_likelihood (google.cloud.vision_v1p3beta1.types.Likelihood): + Headwear likelihood. + """ + + class Landmark(proto.Message): + r"""A face-specific landmark (for example, a face feature). + + Attributes: + type_ (google.cloud.vision_v1p3beta1.types.FaceAnnotation.Landmark.Type): + Face landmark type. + position (google.cloud.vision_v1p3beta1.types.Position): + Face landmark position. + """ + class Type(proto.Enum): + r"""Face landmark (feature) type. Left and right are defined from the + vantage of the viewer of the image without considering mirror + projections typical of photos. So, ``LEFT_EYE``, typically, is the + person's right eye. + + Values: + UNKNOWN_LANDMARK (0): + Unknown face landmark detected. Should not be + filled. + LEFT_EYE (1): + Left eye. + RIGHT_EYE (2): + Right eye. + LEFT_OF_LEFT_EYEBROW (3): + Left of left eyebrow. + RIGHT_OF_LEFT_EYEBROW (4): + Right of left eyebrow. + LEFT_OF_RIGHT_EYEBROW (5): + Left of right eyebrow. + RIGHT_OF_RIGHT_EYEBROW (6): + Right of right eyebrow. + MIDPOINT_BETWEEN_EYES (7): + Midpoint between eyes. + NOSE_TIP (8): + Nose tip. + UPPER_LIP (9): + Upper lip. + LOWER_LIP (10): + Lower lip. + MOUTH_LEFT (11): + Mouth left. + MOUTH_RIGHT (12): + Mouth right. + MOUTH_CENTER (13): + Mouth center. + NOSE_BOTTOM_RIGHT (14): + Nose, bottom right. + NOSE_BOTTOM_LEFT (15): + Nose, bottom left. + NOSE_BOTTOM_CENTER (16): + Nose, bottom center. + LEFT_EYE_TOP_BOUNDARY (17): + Left eye, top boundary. + LEFT_EYE_RIGHT_CORNER (18): + Left eye, right corner. + LEFT_EYE_BOTTOM_BOUNDARY (19): + Left eye, bottom boundary. + LEFT_EYE_LEFT_CORNER (20): + Left eye, left corner. + RIGHT_EYE_TOP_BOUNDARY (21): + Right eye, top boundary. + RIGHT_EYE_RIGHT_CORNER (22): + Right eye, right corner. + RIGHT_EYE_BOTTOM_BOUNDARY (23): + Right eye, bottom boundary. + RIGHT_EYE_LEFT_CORNER (24): + Right eye, left corner. + LEFT_EYEBROW_UPPER_MIDPOINT (25): + Left eyebrow, upper midpoint. + RIGHT_EYEBROW_UPPER_MIDPOINT (26): + Right eyebrow, upper midpoint. + LEFT_EAR_TRAGION (27): + Left ear tragion. + RIGHT_EAR_TRAGION (28): + Right ear tragion. + LEFT_EYE_PUPIL (29): + Left eye pupil. + RIGHT_EYE_PUPIL (30): + Right eye pupil. + FOREHEAD_GLABELLA (31): + Forehead glabella. + CHIN_GNATHION (32): + Chin gnathion. + CHIN_LEFT_GONION (33): + Chin left gonion. + CHIN_RIGHT_GONION (34): + Chin right gonion. + """ + UNKNOWN_LANDMARK = 0 + LEFT_EYE = 1 + RIGHT_EYE = 2 + LEFT_OF_LEFT_EYEBROW = 3 + RIGHT_OF_LEFT_EYEBROW = 4 + LEFT_OF_RIGHT_EYEBROW = 5 + RIGHT_OF_RIGHT_EYEBROW = 6 + MIDPOINT_BETWEEN_EYES = 7 + NOSE_TIP = 8 + UPPER_LIP = 9 + LOWER_LIP = 10 + MOUTH_LEFT = 11 + MOUTH_RIGHT = 12 + MOUTH_CENTER = 13 + NOSE_BOTTOM_RIGHT = 14 + NOSE_BOTTOM_LEFT = 15 + NOSE_BOTTOM_CENTER = 16 + LEFT_EYE_TOP_BOUNDARY = 17 + LEFT_EYE_RIGHT_CORNER = 18 + LEFT_EYE_BOTTOM_BOUNDARY = 19 + LEFT_EYE_LEFT_CORNER = 20 + RIGHT_EYE_TOP_BOUNDARY = 21 + RIGHT_EYE_RIGHT_CORNER = 22 + RIGHT_EYE_BOTTOM_BOUNDARY = 23 + RIGHT_EYE_LEFT_CORNER = 24 + LEFT_EYEBROW_UPPER_MIDPOINT = 25 + RIGHT_EYEBROW_UPPER_MIDPOINT = 26 + LEFT_EAR_TRAGION = 27 + RIGHT_EAR_TRAGION = 28 + LEFT_EYE_PUPIL = 29 + RIGHT_EYE_PUPIL = 30 + FOREHEAD_GLABELLA = 31 + CHIN_GNATHION = 32 + CHIN_LEFT_GONION = 33 + CHIN_RIGHT_GONION = 34 + + type_: 'FaceAnnotation.Landmark.Type' = proto.Field( + proto.ENUM, + number=3, + enum='FaceAnnotation.Landmark.Type', + ) + position: geometry.Position = proto.Field( + proto.MESSAGE, + number=4, + message=geometry.Position, + ) + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + fd_bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + landmarks: MutableSequence[Landmark] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=Landmark, + ) + roll_angle: float = proto.Field( + proto.FLOAT, + number=4, + ) + pan_angle: float = proto.Field( + proto.FLOAT, + number=5, + ) + tilt_angle: float = proto.Field( + proto.FLOAT, + number=6, + ) + detection_confidence: float = proto.Field( + proto.FLOAT, + number=7, + ) + landmarking_confidence: float = proto.Field( + proto.FLOAT, + number=8, + ) + joy_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + sorrow_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=10, + enum='Likelihood', + ) + anger_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=11, + enum='Likelihood', + ) + surprise_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=12, + enum='Likelihood', + ) + under_exposed_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=13, + enum='Likelihood', + ) + blurred_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=14, + enum='Likelihood', + ) + headwear_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=15, + enum='Likelihood', + ) + + +class LocationInfo(proto.Message): + r"""Detected entity location information. + + Attributes: + lat_lng (google.type.latlng_pb2.LatLng): + lat/long location coordinates. + """ + + lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + + +class Property(proto.Message): + r"""A ``Property`` consists of a user-supplied name/value pair. + + Attributes: + name (str): + Name of the property. + value (str): + Value of the property. + uint64_value (int): + Value of numeric properties. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + uint64_value: int = proto.Field( + proto.UINT64, + number=3, + ) + + +class EntityAnnotation(proto.Message): + r"""Set of detected entity features. + + Attributes: + mid (str): + Opaque entity ID. Some IDs may be available in `Google + Knowledge Graph Search + API `__. + locale (str): + The language code for the locale in which the entity textual + ``description`` is expressed. + description (str): + Entity textual description, expressed in its ``locale`` + language. + score (float): + Overall score of the result. Range [0, 1]. + confidence (float): + **Deprecated. Use ``score`` instead.** The accuracy of the + entity detection in an image. For example, for an image in + which the "Eiffel Tower" entity is detected, this field + represents the confidence that there is a tower in the query + image. Range [0, 1]. + topicality (float): + The relevancy of the ICA (Image Content Annotation) label to + the image. For example, the relevancy of "tower" is likely + higher to an image containing the detected "Eiffel Tower" + than to an image containing a detected distant towering + building, even though the confidence that there is a tower + in each image may be the same. Range [0, 1]. + bounding_poly (google.cloud.vision_v1p3beta1.types.BoundingPoly): + Image region to which this entity belongs. Not produced for + ``LABEL_DETECTION`` features. + locations (MutableSequence[google.cloud.vision_v1p3beta1.types.LocationInfo]): + The location information for the detected entity. Multiple + ``LocationInfo`` elements can be present because one + location may indicate the location of the scene in the + image, and another location may indicate the location of the + place where the image was taken. Location information is + usually present for landmarks. + properties (MutableSequence[google.cloud.vision_v1p3beta1.types.Property]): + Some entities may have optional user-supplied ``Property`` + (name/value) fields, such a score or string that qualifies + the entity. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + locale: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + topicality: float = proto.Field( + proto.FLOAT, + number=6, + ) + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=7, + message=geometry.BoundingPoly, + ) + locations: MutableSequence['LocationInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message='LocationInfo', + ) + properties: MutableSequence['Property'] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message='Property', + ) + + +class LocalizedObjectAnnotation(proto.Message): + r"""Set of detected objects with bounding boxes. + + Attributes: + mid (str): + Object ID that should align with + EntityAnnotation mid. + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + name (str): + Object name, expressed in its ``language_code`` language. + score (float): + Score of the result. Range [0, 1]. + bounding_poly (google.cloud.vision_v1p3beta1.types.BoundingPoly): + Image region to which this object belongs. + This must be populated. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=5, + message=geometry.BoundingPoly, + ) + + +class SafeSearchAnnotation(proto.Message): + r"""Set of features pertaining to the image, computed by computer + vision methods over safe-search verticals (for example, adult, + spoof, medical, violence). + + Attributes: + adult (google.cloud.vision_v1p3beta1.types.Likelihood): + Represents the adult content likelihood for + the image. Adult content may contain elements + such as nudity, pornographic images or cartoons, + or sexual activities. + spoof (google.cloud.vision_v1p3beta1.types.Likelihood): + Spoof likelihood. The likelihood that an + modification was made to the image's canonical + version to make it appear funny or offensive. + medical (google.cloud.vision_v1p3beta1.types.Likelihood): + Likelihood that this is a medical image. + violence (google.cloud.vision_v1p3beta1.types.Likelihood): + Likelihood that this image contains violent + content. + racy (google.cloud.vision_v1p3beta1.types.Likelihood): + Likelihood that the request image contains + racy content. Racy content may include (but is + not limited to) skimpy or sheer clothing, + strategically covered nudity, lewd or + provocative poses, or close-ups of sensitive + body areas. + """ + + adult: 'Likelihood' = proto.Field( + proto.ENUM, + number=1, + enum='Likelihood', + ) + spoof: 'Likelihood' = proto.Field( + proto.ENUM, + number=2, + enum='Likelihood', + ) + medical: 'Likelihood' = proto.Field( + proto.ENUM, + number=3, + enum='Likelihood', + ) + violence: 'Likelihood' = proto.Field( + proto.ENUM, + number=4, + enum='Likelihood', + ) + racy: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + + +class LatLongRect(proto.Message): + r"""Rectangle determined by min and max ``LatLng`` pairs. + + Attributes: + min_lat_lng (google.type.latlng_pb2.LatLng): + Min lat/long pair. + max_lat_lng (google.type.latlng_pb2.LatLng): + Max lat/long pair. + """ + + min_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + max_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=2, + message=latlng_pb2.LatLng, + ) + + +class ColorInfo(proto.Message): + r"""Color information consists of RGB channels, score, and the + fraction of the image that the color occupies in the image. + + Attributes: + color (google.type.color_pb2.Color): + RGB components of the color. + score (float): + Image-specific score for this color. Value in range [0, 1]. + pixel_fraction (float): + The fraction of pixels the color occupies in the image. + Value in range [0, 1]. + """ + + color: color_pb2.Color = proto.Field( + proto.MESSAGE, + number=1, + message=color_pb2.Color, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + pixel_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class DominantColorsAnnotation(proto.Message): + r"""Set of dominant colors and their corresponding scores. + + Attributes: + colors (MutableSequence[google.cloud.vision_v1p3beta1.types.ColorInfo]): + RGB color values with their score and pixel + fraction. + """ + + colors: MutableSequence['ColorInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ColorInfo', + ) + + +class ImageProperties(proto.Message): + r"""Stores image properties, such as dominant colors. + + Attributes: + dominant_colors (google.cloud.vision_v1p3beta1.types.DominantColorsAnnotation): + If present, dominant colors completed + successfully. + """ + + dominant_colors: 'DominantColorsAnnotation' = proto.Field( + proto.MESSAGE, + number=1, + message='DominantColorsAnnotation', + ) + + +class CropHint(proto.Message): + r"""Single crop hint that is used to generate a new crop when + serving an image. + + Attributes: + bounding_poly (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The bounding polygon for the crop region. The coordinates of + the bounding box are in the original image's scale, as + returned in ``ImageParams``. + confidence (float): + Confidence of this being a salient region. Range [0, 1]. + importance_fraction (float): + Fraction of importance of this salient region + with respect to the original image. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + importance_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class CropHintsAnnotation(proto.Message): + r"""Set of crop hints that are used to generate new crops when + serving images. + + Attributes: + crop_hints (MutableSequence[google.cloud.vision_v1p3beta1.types.CropHint]): + Crop hint results. + """ + + crop_hints: MutableSequence['CropHint'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='CropHint', + ) + + +class CropHintsParams(proto.Message): + r"""Parameters for crop hints annotation request. + + Attributes: + aspect_ratios (MutableSequence[float]): + Aspect ratios in floats, representing the + ratio of the width to the height of the image. + For example, if the desired aspect ratio is 4/3, + the corresponding float value should be 1.33333. + If not specified, the best possible crop is + returned. The number of provided aspect ratios + is limited to a maximum of 16; any aspect ratios + provided after the 16th are ignored. + """ + + aspect_ratios: MutableSequence[float] = proto.RepeatedField( + proto.FLOAT, + number=1, + ) + + +class WebDetectionParams(proto.Message): + r"""Parameters for web detection request. + + Attributes: + include_geo_results (bool): + Whether to include results derived from the + geo information in the image. + """ + + include_geo_results: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class TextDetectionParams(proto.Message): + r"""Parameters for text detections. This is used to control + TEXT_DETECTION and DOCUMENT_TEXT_DETECTION features. + + Attributes: + enable_text_detection_confidence_score (bool): + By default, Cloud Vision API only includes confidence score + for DOCUMENT_TEXT_DETECTION result. Set the flag to true to + include confidence score for TEXT_DETECTION as well. + advanced_ocr_options (MutableSequence[str]): + A list of advanced OCR options to fine-tune + OCR behavior. + """ + + enable_text_detection_confidence_score: bool = proto.Field( + proto.BOOL, + number=9, + ) + advanced_ocr_options: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + + +class ImageContext(proto.Message): + r"""Image context and/or feature-specific parameters. + + Attributes: + lat_long_rect (google.cloud.vision_v1p3beta1.types.LatLongRect): + Not used. + language_hints (MutableSequence[str]): + List of languages to use for TEXT_DETECTION. In most cases, + an empty value yields the best results since it enables + automatic language detection. For languages based on the + Latin alphabet, setting ``language_hints`` is not needed. In + rare cases, when the language of the text in the image is + known, setting a hint will help get better results (although + it will be a significant hindrance if the hint is wrong). + Text detection returns an error if one or more of the + specified languages is not one of the `supported + languages `__. + crop_hints_params (google.cloud.vision_v1p3beta1.types.CropHintsParams): + Parameters for crop hints annotation request. + product_search_params (google.cloud.vision_v1p3beta1.types.ProductSearchParams): + Parameters for product search. + web_detection_params (google.cloud.vision_v1p3beta1.types.WebDetectionParams): + Parameters for web detection. + text_detection_params (google.cloud.vision_v1p3beta1.types.TextDetectionParams): + Parameters for text detection and document + text detection. + """ + + lat_long_rect: 'LatLongRect' = proto.Field( + proto.MESSAGE, + number=1, + message='LatLongRect', + ) + language_hints: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + crop_hints_params: 'CropHintsParams' = proto.Field( + proto.MESSAGE, + number=4, + message='CropHintsParams', + ) + product_search_params: product_search.ProductSearchParams = proto.Field( + proto.MESSAGE, + number=5, + message=product_search.ProductSearchParams, + ) + web_detection_params: 'WebDetectionParams' = proto.Field( + proto.MESSAGE, + number=6, + message='WebDetectionParams', + ) + text_detection_params: 'TextDetectionParams' = proto.Field( + proto.MESSAGE, + number=12, + message='TextDetectionParams', + ) + + +class AnnotateImageRequest(proto.Message): + r"""Request for performing Google Cloud Vision API tasks over a + user-provided image, with user-requested features. + + Attributes: + image (google.cloud.vision_v1p3beta1.types.Image): + The image to be processed. + features (MutableSequence[google.cloud.vision_v1p3beta1.types.Feature]): + Requested features. + image_context (google.cloud.vision_v1p3beta1.types.ImageContext): + Additional context that may accompany the + image. + """ + + image: 'Image' = proto.Field( + proto.MESSAGE, + number=1, + message='Image', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + + +class ImageAnnotationContext(proto.Message): + r"""If an image was produced from a file (e.g. a PDF), this + message gives information about the source of that image. + + Attributes: + uri (str): + The URI of the file used to produce the + image. + page_number (int): + If the file was a PDF or TIFF, this field + gives the page number within the file used to + produce the image. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + page_number: int = proto.Field( + proto.INT32, + number=2, + ) + + +class AnnotateImageResponse(proto.Message): + r"""Response to an image annotation request. + + Attributes: + face_annotations (MutableSequence[google.cloud.vision_v1p3beta1.types.FaceAnnotation]): + If present, face detection has completed + successfully. + landmark_annotations (MutableSequence[google.cloud.vision_v1p3beta1.types.EntityAnnotation]): + If present, landmark detection has completed + successfully. + logo_annotations (MutableSequence[google.cloud.vision_v1p3beta1.types.EntityAnnotation]): + If present, logo detection has completed + successfully. + label_annotations (MutableSequence[google.cloud.vision_v1p3beta1.types.EntityAnnotation]): + If present, label detection has completed + successfully. + localized_object_annotations (MutableSequence[google.cloud.vision_v1p3beta1.types.LocalizedObjectAnnotation]): + If present, localized object detection has + completed successfully. This will be sorted + descending by confidence score. + text_annotations (MutableSequence[google.cloud.vision_v1p3beta1.types.EntityAnnotation]): + If present, text (OCR) detection has + completed successfully. + full_text_annotation (google.cloud.vision_v1p3beta1.types.TextAnnotation): + If present, text (OCR) detection or document + (OCR) text detection has completed successfully. + This annotation provides the structural + hierarchy for the OCR detected text. + safe_search_annotation (google.cloud.vision_v1p3beta1.types.SafeSearchAnnotation): + If present, safe-search annotation has + completed successfully. + image_properties_annotation (google.cloud.vision_v1p3beta1.types.ImageProperties): + If present, image properties were extracted + successfully. + crop_hints_annotation (google.cloud.vision_v1p3beta1.types.CropHintsAnnotation): + If present, crop hints have completed + successfully. + web_detection (google.cloud.vision_v1p3beta1.types.WebDetection): + If present, web detection has completed + successfully. + product_search_results (google.cloud.vision_v1p3beta1.types.ProductSearchResults): + If present, product search has completed + successfully. + error (google.rpc.status_pb2.Status): + If set, represents the error message for the operation. Note + that filled-in image annotations are guaranteed to be + correct, even when ``error`` is set. + context (google.cloud.vision_v1p3beta1.types.ImageAnnotationContext): + If present, contextual information is needed + to understand where this image comes from. + """ + + face_annotations: MutableSequence['FaceAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='FaceAnnotation', + ) + landmark_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='EntityAnnotation', + ) + logo_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='EntityAnnotation', + ) + label_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='EntityAnnotation', + ) + localized_object_annotations: MutableSequence['LocalizedObjectAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=22, + message='LocalizedObjectAnnotation', + ) + text_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='EntityAnnotation', + ) + full_text_annotation: text_annotation.TextAnnotation = proto.Field( + proto.MESSAGE, + number=12, + message=text_annotation.TextAnnotation, + ) + safe_search_annotation: 'SafeSearchAnnotation' = proto.Field( + proto.MESSAGE, + number=6, + message='SafeSearchAnnotation', + ) + image_properties_annotation: 'ImageProperties' = proto.Field( + proto.MESSAGE, + number=8, + message='ImageProperties', + ) + crop_hints_annotation: 'CropHintsAnnotation' = proto.Field( + proto.MESSAGE, + number=11, + message='CropHintsAnnotation', + ) + web_detection: gcv_web_detection.WebDetection = proto.Field( + proto.MESSAGE, + number=13, + message=gcv_web_detection.WebDetection, + ) + product_search_results: product_search.ProductSearchResults = proto.Field( + proto.MESSAGE, + number=14, + message=product_search.ProductSearchResults, + ) + error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=9, + message=status_pb2.Status, + ) + context: 'ImageAnnotationContext' = proto.Field( + proto.MESSAGE, + number=21, + message='ImageAnnotationContext', + ) + + +class AnnotateFileResponse(proto.Message): + r"""Response to a single file annotation request. A file may + contain one or more images, which individually have their own + responses. + + Attributes: + input_config (google.cloud.vision_v1p3beta1.types.InputConfig): + Information about the file for which this + response is generated. + responses (MutableSequence[google.cloud.vision_v1p3beta1.types.AnnotateImageResponse]): + Individual responses to images found within + the file. + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='AnnotateImageResponse', + ) + + +class BatchAnnotateImagesRequest(proto.Message): + r"""Multiple image annotation requests are batched into a single + service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p3beta1.types.AnnotateImageRequest]): + Individual image annotation requests for this + batch. + """ + + requests: MutableSequence['AnnotateImageRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageRequest', + ) + + +class BatchAnnotateImagesResponse(proto.Message): + r"""Response to a batch image annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1p3beta1.types.AnnotateImageResponse]): + Individual responses to image annotation + requests within the batch. + """ + + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageResponse', + ) + + +class AsyncAnnotateFileRequest(proto.Message): + r"""An offline file annotation request. + + Attributes: + input_config (google.cloud.vision_v1p3beta1.types.InputConfig): + Required. Information about the input file. + features (MutableSequence[google.cloud.vision_v1p3beta1.types.Feature]): + Required. Requested features. + image_context (google.cloud.vision_v1p3beta1.types.ImageContext): + Additional context that may accompany the + image(s) in the file. + output_config (google.cloud.vision_v1p3beta1.types.OutputConfig): + Required. The desired output location and + metadata (e.g. format). + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=4, + message='OutputConfig', + ) + + +class AsyncAnnotateFileResponse(proto.Message): + r"""The response for a single offline file annotation request. + + Attributes: + output_config (google.cloud.vision_v1p3beta1.types.OutputConfig): + The output location and metadata from + AsyncAnnotateFileRequest. + """ + + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='OutputConfig', + ) + + +class AsyncBatchAnnotateFilesRequest(proto.Message): + r"""Multiple async file annotation requests are batched into a + single service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p3beta1.types.AsyncAnnotateFileRequest]): + Required. Individual async file annotation + requests for this batch. + """ + + requests: MutableSequence['AsyncAnnotateFileRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AsyncAnnotateFileRequest', + ) + + +class AsyncBatchAnnotateFilesResponse(proto.Message): + r"""Response to an async batch file annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1p3beta1.types.AsyncAnnotateFileResponse]): + The list of file annotation responses, one + for each request in + AsyncBatchAnnotateFilesRequest. + """ + + responses: MutableSequence['AsyncAnnotateFileResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AsyncAnnotateFileResponse', + ) + + +class InputConfig(proto.Message): + r"""The desired input location and metadata. + + Attributes: + gcs_source (google.cloud.vision_v1p3beta1.types.GcsSource): + The Google Cloud Storage location to read the + input from. + mime_type (str): + The type of the file. Currently only + "application/pdf" and "image/tiff" are + supported. Wildcards are not supported. + """ + + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=1, + message='GcsSource', + ) + mime_type: str = proto.Field( + proto.STRING, + number=2, + ) + + +class OutputConfig(proto.Message): + r"""The desired output location and metadata. + + Attributes: + gcs_destination (google.cloud.vision_v1p3beta1.types.GcsDestination): + The Google Cloud Storage location to write + the output(s) to. + batch_size (int): + The max number of response protos to put into each output + JSON file on Google Cloud Storage. The valid range is [1, + 100]. If not specified, the default value is 20. + + For example, for one pdf file with 100 pages, 100 response + protos will be generated. If ``batch_size`` = 20, then 5 + json files each containing 20 response protos will be + written under the prefix ``gcs_destination``.\ ``uri``. + + Currently, batch_size only applies to GcsDestination, with + potential future support for other output configurations. + """ + + gcs_destination: 'GcsDestination' = proto.Field( + proto.MESSAGE, + number=1, + message='GcsDestination', + ) + batch_size: int = proto.Field( + proto.INT32, + number=2, + ) + + +class GcsSource(proto.Message): + r"""The Google Cloud Storage location where the input will be + read from. + + Attributes: + uri (str): + Google Cloud Storage URI for the input file. + This must only be a Google Cloud Storage object. + Wildcards are not currently supported. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GcsDestination(proto.Message): + r"""The Google Cloud Storage location where the output will be + written to. + + Attributes: + uri (str): + Google Cloud Storage URI where the results will be stored. + Results will be in JSON format and preceded by its + corresponding input URI. This field can either represent a + single file, or a prefix for multiple outputs. Prefixes must + end in a ``/``. + + Examples: + + - File: gs://bucket-name/filename.json + - Prefix: gs://bucket-name/prefix/here/ + - File: gs://bucket-name/prefix/here + + If multiple outputs, each response is still + AnnotateFileResponse, each of which contains some subset of + the full list of AnnotateImageResponse. Multiple outputs can + happen if, for example, the output JSON is too large and + overflows into multiple sharded files. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class OperationMetadata(proto.Message): + r"""Contains metadata for the BatchAnnotateImages operation. + + Attributes: + state (google.cloud.vision_v1p3beta1.types.OperationMetadata.State): + Current state of the batch operation. + create_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request was received. + update_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the operation result was last + updated. + """ + class State(proto.Enum): + r"""Batch operation states. + + Values: + STATE_UNSPECIFIED (0): + Invalid. + CREATED (1): + Request is received. + RUNNING (2): + Request is actively being processed. + DONE (3): + The batch processing is done. + CANCELLED (4): + The batch processing was cancelled. + """ + STATE_UNSPECIFIED = 0 + CREATED = 1 + RUNNING = 2 + DONE = 3 + CANCELLED = 4 + + state: State = proto.Field( + proto.ENUM, + number=1, + enum=State, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/product_search.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/product_search.py new file mode 100644 index 00000000..d2260589 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/product_search.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p3beta1.types import geometry +from google.cloud.vision_v1p3beta1.types import product_search_service +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p3beta1', + manifest={ + 'ProductSearchParams', + 'ProductSearchResults', + }, +) + + +class ProductSearchParams(proto.Message): + r"""Parameters for a product search request. + + Attributes: + bounding_poly (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The bounding polygon around the area of + interest in the image. If it is not specified, + system discretion will be applied. + product_set (str): + The resource name of a + [ProductSet][google.cloud.vision.v1p3beta1.ProductSet] to be + searched for similar images. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID``. + product_categories (MutableSequence[str]): + The list of product categories to search in. + Currently, we only consider the first category, + and either "homegoods-v2", "apparel-v2", + "toys-v2", "packagedgoods-v1", or "general-v1" + should be specified. The legacy categories + "homegoods", "apparel", and "toys" are still + supported but will be deprecated. For new + products, please use "homegoods-v2", + "apparel-v2", or "toys-v2" for better product + search accuracy. It is recommended to migrate + existing products to these categories as well. + filter (str): + The filtering expression. This can be used to + restrict search results based on Product labels. + We currently support an AND of OR of key-value + expressions, where each expression within an OR + must have the same key. An '=' should be used to + connect the key and value. + + For example, "(color = red OR color = blue) AND + brand = Google" is acceptable, but "(color = red + OR brand = Google)" is not acceptable. "color: + red" is not acceptable because it uses a ':' + instead of an '='. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=9, + message=geometry.BoundingPoly, + ) + product_set: str = proto.Field( + proto.STRING, + number=6, + ) + product_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + filter: str = proto.Field( + proto.STRING, + number=8, + ) + + +class ProductSearchResults(proto.Message): + r"""Results for a product search request. + + Attributes: + index_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp of the index which provided these + results. Products added to the product set and + products removed from the product set after this + time are not reflected in the current results. + results (MutableSequence[google.cloud.vision_v1p3beta1.types.ProductSearchResults.Result]): + List of results, one for each product match. + product_grouped_results (MutableSequence[google.cloud.vision_v1p3beta1.types.ProductSearchResults.GroupedResult]): + List of results grouped by products detected + in the query image. Each entry corresponds to + one bounding polygon in the query image, and + contains the matching products specific to that + region. There may be duplicate product matches + in the union of all the per-product results. + """ + + class Result(proto.Message): + r"""Information about a product. + + Attributes: + product (google.cloud.vision_v1p3beta1.types.Product): + The Product. + score (float): + A confidence level on the match, ranging from + 0 (no confidence) to 1 (full confidence). + image (str): + The resource name of the image from the + product that is the closest match to the query. + """ + + product: product_search_service.Product = proto.Field( + proto.MESSAGE, + number=1, + message=product_search_service.Product, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + image: str = proto.Field( + proto.STRING, + number=3, + ) + + class ObjectAnnotation(proto.Message): + r"""Prediction for what the object in the bounding box is. + + Attributes: + mid (str): + Object ID that should align with + EntityAnnotation mid. + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + name (str): + Object name, expressed in its ``language_code`` language. + score (float): + Score of the result. Range [0, 1]. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + + class GroupedResult(proto.Message): + r"""Information about the products similar to a single product in + a query image. + + Attributes: + bounding_poly (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The bounding polygon around the product + detected in the query image. + results (MutableSequence[google.cloud.vision_v1p3beta1.types.ProductSearchResults.Result]): + List of results, one for each product match. + object_annotations (MutableSequence[google.cloud.vision_v1p3beta1.types.ProductSearchResults.ObjectAnnotation]): + List of generic predictions for the object in + the bounding box. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + results: MutableSequence['ProductSearchResults.Result'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='ProductSearchResults.Result', + ) + object_annotations: MutableSequence['ProductSearchResults.ObjectAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='ProductSearchResults.ObjectAnnotation', + ) + + index_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + results: MutableSequence[Result] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=Result, + ) + product_grouped_results: MutableSequence[GroupedResult] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=GroupedResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/product_search_service.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/product_search_service.py new file mode 100644 index 00000000..ea2296c3 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/product_search_service.py @@ -0,0 +1,1026 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p3beta1.types import geometry +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p3beta1', + manifest={ + 'Product', + 'ProductSet', + 'ReferenceImage', + 'CreateProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'GetProductRequest', + 'UpdateProductRequest', + 'DeleteProductRequest', + 'CreateProductSetRequest', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'GetProductSetRequest', + 'UpdateProductSetRequest', + 'DeleteProductSetRequest', + 'CreateReferenceImageRequest', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'GetReferenceImageRequest', + 'DeleteReferenceImageRequest', + 'AddProductToProductSetRequest', + 'RemoveProductFromProductSetRequest', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'BatchOperationMetadata', + }, +) + + +class Product(proto.Message): + r"""A Product contains ReferenceImages. + + Attributes: + name (str): + The resource name of the product. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This field is ignored when creating a product. + display_name (str): + The user-provided name for this Product. Must + not be empty. Must be at most 4096 characters + long. + description (str): + User-provided metadata to be stored with this + product. Must be at most 4096 characters long. + product_category (str): + Immutable. The category for the product + identified by the reference image. This should + be either "homegoods-v2", "apparel-v2", or + "toys-v2". The legacy categories "homegoods", + "apparel", and "toys" are still supported, but + these should not be used for new products. + product_labels (MutableSequence[google.cloud.vision_v1p3beta1.types.Product.KeyValue]): + Key-value pairs that can be attached to a product. At query + time, constraints can be specified based on the + product_labels. + + Note that integer values can be provided as strings, e.g. + "1199". Only strings with integer values can match a + range-based restriction which is to be supported soon. + + Multiple values can be assigned to the same key. One product + may have up to 100 product_labels. + """ + + class KeyValue(proto.Message): + r"""A product label represented as a key-value pair. + + Attributes: + key (str): + The key of the label attached to the product. + Cannot be empty and cannot exceed 128 bytes. + value (str): + The value of the label attached to the + product. Cannot be empty and cannot exceed 128 + bytes. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + product_category: str = proto.Field( + proto.STRING, + number=4, + ) + product_labels: MutableSequence[KeyValue] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=KeyValue, + ) + + +class ProductSet(proto.Message): + r"""A ProductSet contains Products. A ProductSet can contain a + maximum of 1 million reference images. If the limit is exceeded, + periodic indexing will fail. + + Attributes: + name (str): + The resource name of the ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID``. + + This field is ignored when creating a ProductSet. + display_name (str): + The user-provided name for this ProductSet. + Must not be empty. Must be at most 4096 + characters long. + index_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time at which this + ProductSet was last indexed. Query results will + reflect all updates before this time. If this + ProductSet has never been indexed, this field is + 0. + + This field is ignored when creating a + ProductSet. + index_error (google.rpc.status_pb2.Status): + Output only. If there was an error with + indexing the product set, the field is + populated. + + This field is ignored when creating a + ProductSet. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + index_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + index_error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=4, + message=status_pb2.Status, + ) + + +class ReferenceImage(proto.Message): + r"""A ``ReferenceImage`` represents a product image and its associated + metadata, such as bounding boxes. + + Attributes: + name (str): + The resource name of the reference image. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This field is ignored when creating a reference image. + uri (str): + Required. The Google Cloud Storage URI of the reference + image. + + The URI must start with ``gs://``. + bounding_polys (MutableSequence[google.cloud.vision_v1p3beta1.types.BoundingPoly]): + Optional. Bounding polygons around the areas + of interest in the reference image. If this + field is empty, the system will try to detect + regions of interest. At most 10 bounding + polygons will be used. + + The provided shape is converted into a + non-rotated rectangle. Once converted, the small + edge of the rectangle must be greater than or + equal to 300 pixels. The aspect ratio must be + 1:4 or less (i.e. 1:3 is ok; 1:5 is not). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + uri: str = proto.Field( + proto.STRING, + number=2, + ) + bounding_polys: MutableSequence[geometry.BoundingPoly] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=geometry.BoundingPoly, + ) + + +class CreateProductRequest(proto.Message): + r"""Request message for the ``CreateProduct`` method. + + Attributes: + parent (str): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + product (google.cloud.vision_v1p3beta1.types.Product): + Required. The product to create. + product_id (str): + A user-supplied resource id for this Product. If set, the + server will attempt to use this value as the resource id. If + it is already in use, an error is returned with code + ALREADY_EXISTS. Must be at most 128 characters long. It + cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product: 'Product' = proto.Field( + proto.MESSAGE, + number=2, + message='Product', + ) + product_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsRequest(proto.Message): + r"""Request message for the ``ListProducts`` method. + + Attributes: + parent (str): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsResponse(proto.Message): + r"""Response message for the ``ListProducts`` method. + + Attributes: + products (MutableSequence[google.cloud.vision_v1p3beta1.types.Product]): + List of products. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Product', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetProductRequest(proto.Message): + r"""Request message for the ``GetProduct`` method. + + Attributes: + name (str): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductRequest(proto.Message): + r"""Request message for the ``UpdateProduct`` method. + + Attributes: + product (google.cloud.vision_v1p3beta1.types.Product): + Required. The Product resource which replaces + the one on the server. product.name is + immutable. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that specifies + which fields to update. If update_mask isn't specified, all + mutable fields are to be updated. Valid mask paths include + ``product_labels``, ``display_name``, and ``description``. + """ + + product: 'Product' = proto.Field( + proto.MESSAGE, + number=1, + message='Product', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteProductRequest(proto.Message): + r"""Request message for the ``DeleteProduct`` method. + + Attributes: + name (str): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateProductSetRequest(proto.Message): + r"""Request message for the ``CreateProductSet`` method. + + Attributes: + parent (str): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + product_set (google.cloud.vision_v1p3beta1.types.ProductSet): + Required. The ProductSet to create. + product_set_id (str): + A user-supplied resource id for this ProductSet. If set, the + server will attempt to use this value as the resource id. If + it is already in use, an error is returned with code + ALREADY_EXISTS. Must be at most 128 characters long. It + cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product_set: 'ProductSet' = proto.Field( + proto.MESSAGE, + number=2, + message='ProductSet', + ) + product_set_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductSetsRequest(proto.Message): + r"""Request message for the ``ListProductSets`` method. + + Attributes: + parent (str): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductSetsResponse(proto.Message): + r"""Response message for the ``ListProductSets`` method. + + Attributes: + product_sets (MutableSequence[google.cloud.vision_v1p3beta1.types.ProductSet]): + List of ProductSets. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + product_sets: MutableSequence['ProductSet'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ProductSet', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetProductSetRequest(proto.Message): + r"""Request message for the ``GetProductSet`` method. + + Attributes: + name (str): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductSetRequest(proto.Message): + r"""Request message for the ``UpdateProductSet`` method. + + Attributes: + product_set (google.cloud.vision_v1p3beta1.types.ProductSet): + Required. The ProductSet resource which + replaces the one on the server. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that specifies + which fields to update. If update_mask isn't specified, all + mutable fields are to be updated. Valid mask path is + ``display_name``. + """ + + product_set: 'ProductSet' = proto.Field( + proto.MESSAGE, + number=1, + message='ProductSet', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteProductSetRequest(proto.Message): + r"""Request message for the ``DeleteProductSet`` method. + + Attributes: + name (str): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateReferenceImageRequest(proto.Message): + r"""Request message for the ``CreateReferenceImage`` method. + + Attributes: + parent (str): + Required. Resource name of the product in which to create + the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + reference_image (google.cloud.vision_v1p3beta1.types.ReferenceImage): + Required. The reference image to create. + If an image ID is specified, it is ignored. + reference_image_id (str): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value as + the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + reference_image: 'ReferenceImage' = proto.Field( + proto.MESSAGE, + number=2, + message='ReferenceImage', + ) + reference_image_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListReferenceImagesRequest(proto.Message): + r"""Request message for the ``ListReferenceImages`` method. + + Attributes: + parent (str): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + A token identifying a page of results to be returned. This + is the value of ``nextPageToken`` returned in a previous + reference image list request. + + Defaults to the first page if not specified. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListReferenceImagesResponse(proto.Message): + r"""Response message for the ``ListReferenceImages`` method. + + Attributes: + reference_images (MutableSequence[google.cloud.vision_v1p3beta1.types.ReferenceImage]): + The list of reference images. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + next_page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + @property + def raw_page(self): + return self + + reference_images: MutableSequence['ReferenceImage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ReferenceImage', + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetReferenceImageRequest(proto.Message): + r"""Request message for the ``GetReferenceImage`` method. + + Attributes: + name (str): + Required. The resource name of the ReferenceImage to get. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class DeleteReferenceImageRequest(proto.Message): + r"""Request message for the ``DeleteReferenceImage`` method. + + Attributes: + name (str): + Required. The resource name of the reference image to + delete. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AddProductToProductSetRequest(proto.Message): + r"""Request message for the ``AddProductToProductSet`` method. + + Attributes: + name (str): + Required. The resource name for the ProductSet to modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + product (str): + Required. The resource name for the Product to be added to + this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + product: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RemoveProductFromProductSetRequest(proto.Message): + r"""Request message for the ``RemoveProductFromProductSet`` method. + + Attributes: + name (str): + Required. The resource name for the ProductSet to modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + product (str): + Required. The resource name for the Product to be removed + from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + product: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ListProductsInProductSetRequest(proto.Message): + r"""Request message for the ``ListProductsInProductSet`` method. + + Attributes: + name (str): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsInProductSetResponse(proto.Message): + r"""Response message for the ``ListProductsInProductSet`` method. + + Attributes: + products (MutableSequence[google.cloud.vision_v1p3beta1.types.Product]): + The list of Products. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Product', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ImportProductSetsGcsSource(proto.Message): + r"""The Google Cloud Storage location for a csv file which + preserves a list of ImportProductSetRequests in each line. + + Attributes: + csv_file_uri (str): + The Google Cloud Storage URI of the input csv file. + + The URI must start with ``gs://``. + + The format of the input csv file should be one image per + line. In each line, there are 6 columns. + + 1. image_uri 2, image_id + 2. product_set_id + 3. product_id 5, product_category 6, product_display_name 7, + labels + 4. bounding_poly + + Columns 1, 3, 4, and 5 are required, other columns are + optional. A new ProductSet/Product with the same id will be + created on the fly if the ProductSet/Product specified by + product_set_id/product_id does not exist. + + The image_id field is optional but has to be unique if + provided. If it is empty, we will automatically assign an + unique id to the image. + + The product_display_name field is optional. If it is empty, + a space (" ") is used as the place holder for the product + display_name, which can be updated later through the + realtime API. + + If the Product with product_id already exists, the fields + product_display_name, product_category and labels are + ignored. + + If a Product doesn't exist and needs to be created on the + fly, the product_display_name field refers to + [Product.display_name][google.cloud.vision.v1p3beta1.Product.display_name], + the product_category field refers to + [Product.product_category][google.cloud.vision.v1p3beta1.Product.product_category], + and the labels field refers to [Product.labels][]. + + Labels (optional) should be a line containing a list of + comma-separated key-value pairs, with the format + "key_1=value_1,key_2=value_2,...,key_n=value_n". + + The bounding_poly (optional) field is used to identify one + region of interest from the image in the same manner as + CreateReferenceImage. If no bounding_poly is specified, the + system will try to detect regions of interest automatically. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 20MP). + + Also note that at most one bounding_poly is allowed per + line. If the image contains multiple regions of interest, + the csv should contain one line per region of interest. + + The bounding_poly column should contain an even number of + comma-separated numbers, with the format + "p1_x,p1_y,p2_x,p2_y,...,pn_x,pn_y". Nonnegative integers + should be used for absolute bounding polygons, and float + values in [0, 1] should be used for normalized bounding + polygons. + """ + + csv_file_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ImportProductSetsInputConfig(proto.Message): + r"""The input content for the ``ImportProductSets`` method. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_source (google.cloud.vision_v1p3beta1.types.ImportProductSetsGcsSource): + The Google Cloud Storage location for a csv + file which preserves a list of + ImportProductSetRequests in each line. + + This field is a member of `oneof`_ ``source``. + """ + + gcs_source: 'ImportProductSetsGcsSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='ImportProductSetsGcsSource', + ) + + +class ImportProductSetsRequest(proto.Message): + r"""Request message for the ``ImportProductSets`` method. + + Attributes: + parent (str): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + input_config (google.cloud.vision_v1p3beta1.types.ImportProductSetsInputConfig): + Required. The input content for the list of + requests. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'ImportProductSetsInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportProductSetsInputConfig', + ) + + +class ImportProductSetsResponse(proto.Message): + r"""Response message for the ``ImportProductSets`` method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + Attributes: + reference_images (MutableSequence[google.cloud.vision_v1p3beta1.types.ReferenceImage]): + The list of reference_images that are imported successfully. + statuses (MutableSequence[google.rpc.status_pb2.Status]): + The rpc status for each ImportProductSet request, including + both successes and errors. + + The number of statuses here matches the number of lines in + the csv file, and statuses[i] stores the success or failure + status of processing the i-th line of the csv, starting from + line 0. + """ + + reference_images: MutableSequence['ReferenceImage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ReferenceImage', + ) + statuses: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=status_pb2.Status, + ) + + +class BatchOperationMetadata(proto.Message): + r"""Metadata for the batch operations such as the current state. + + This is included in the ``metadata`` field of the ``Operation`` + returned by the ``GetOperation`` call of the + ``google::longrunning::Operations`` service. + + Attributes: + state (google.cloud.vision_v1p3beta1.types.BatchOperationMetadata.State): + The current state of the batch operation. + submit_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request was submitted + to the server. + end_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request is finished and + [google.longrunning.Operation.done][google.longrunning.Operation.done] + is set to true. + """ + class State(proto.Enum): + r"""Enumerates the possible states that the batch request can be + in. + + Values: + STATE_UNSPECIFIED (0): + Invalid. + PROCESSING (1): + Request is actively being processed. + SUCCESSFUL (2): + The request is done and at least one item has + been successfully processed. + FAILED (3): + The request is done and no item has been + successfully processed. + CANCELLED (4): + The request is done after the + longrunning.Operations.CancelOperation has been + called by the user. Any records that were + processed before the cancel command are output + as specified in the request. + """ + STATE_UNSPECIFIED = 0 + PROCESSING = 1 + SUCCESSFUL = 2 + FAILED = 3 + CANCELLED = 4 + + state: State = proto.Field( + proto.ENUM, + number=1, + enum=State, + ) + submit_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/text_annotation.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/text_annotation.py new file mode 100644 index 00000000..9fe98d74 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/text_annotation.py @@ -0,0 +1,429 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p3beta1.types import geometry + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p3beta1', + manifest={ + 'TextAnnotation', + 'Page', + 'Block', + 'Paragraph', + 'Word', + 'Symbol', + }, +) + + +class TextAnnotation(proto.Message): + r"""TextAnnotation contains a structured representation of OCR extracted + text. The hierarchy of an OCR extracted text structure is like this: + TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol Each + structural component, starting from Page, may further have their own + properties. Properties describe detected languages, breaks etc.. + Please refer to the + [TextAnnotation.TextProperty][google.cloud.vision.v1p3beta1.TextAnnotation.TextProperty] + message definition below for more detail. + + Attributes: + pages (MutableSequence[google.cloud.vision_v1p3beta1.types.Page]): + List of pages detected by OCR. + text (str): + UTF-8 text detected on the pages. + """ + + class DetectedLanguage(proto.Message): + r"""Detected language for a structural component. + + Attributes: + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + confidence (float): + Confidence of detected language. Range [0, 1]. + """ + + language_code: str = proto.Field( + proto.STRING, + number=1, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class DetectedBreak(proto.Message): + r"""Detected start or end of a structural component. + + Attributes: + type_ (google.cloud.vision_v1p3beta1.types.TextAnnotation.DetectedBreak.BreakType): + Detected break type. + is_prefix (bool): + True if break prepends the element. + """ + class BreakType(proto.Enum): + r"""Enum to denote the type of break found. New line, space etc. + + Values: + UNKNOWN (0): + Unknown break label type. + SPACE (1): + Regular space. + SURE_SPACE (2): + Sure space (very wide). + EOL_SURE_SPACE (3): + Line-wrapping break. + HYPHEN (4): + End-line hyphen that is not present in text; does not + co-occur with ``SPACE``, ``LEADER_SPACE``, or + ``LINE_BREAK``. + LINE_BREAK (5): + Line break that ends a paragraph. + """ + UNKNOWN = 0 + SPACE = 1 + SURE_SPACE = 2 + EOL_SURE_SPACE = 3 + HYPHEN = 4 + LINE_BREAK = 5 + + type_: 'TextAnnotation.DetectedBreak.BreakType' = proto.Field( + proto.ENUM, + number=1, + enum='TextAnnotation.DetectedBreak.BreakType', + ) + is_prefix: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class TextProperty(proto.Message): + r"""Additional information detected on the structural component. + + Attributes: + detected_languages (MutableSequence[google.cloud.vision_v1p3beta1.types.TextAnnotation.DetectedLanguage]): + A list of detected languages together with + confidence. + detected_break (google.cloud.vision_v1p3beta1.types.TextAnnotation.DetectedBreak): + Detected start or end of a text segment. + """ + + detected_languages: MutableSequence['TextAnnotation.DetectedLanguage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='TextAnnotation.DetectedLanguage', + ) + detected_break: 'TextAnnotation.DetectedBreak' = proto.Field( + proto.MESSAGE, + number=2, + message='TextAnnotation.DetectedBreak', + ) + + pages: MutableSequence['Page'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Page', + ) + text: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Page(proto.Message): + r"""Detected page from OCR. + + Attributes: + property (google.cloud.vision_v1p3beta1.types.TextAnnotation.TextProperty): + Additional information detected on the page. + width (int): + Page width. For PDFs the unit is points. For + images (including TIFFs) the unit is pixels. + height (int): + Page height. For PDFs the unit is points. For + images (including TIFFs) the unit is pixels. + blocks (MutableSequence[google.cloud.vision_v1p3beta1.types.Block]): + List of blocks of text, images etc on this + page. + confidence (float): + Confidence of the OCR results on the page. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + width: int = proto.Field( + proto.INT32, + number=2, + ) + height: int = proto.Field( + proto.INT32, + number=3, + ) + blocks: MutableSequence['Block'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='Block', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Block(proto.Message): + r"""Logical element on the page. + + Attributes: + property (google.cloud.vision_v1p3beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + block. + bounding_box (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The bounding box for the block. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: + + :: + + 0----1 + | | + 3----2 + + - when it's rotated 180 degrees around the top-left corner + it becomes: + + :: + + 2----3 + | | + 1----0 + + and the vertice order will still be (0, 1, 2, 3). + paragraphs (MutableSequence[google.cloud.vision_v1p3beta1.types.Paragraph]): + List of paragraphs in this block (if this + blocks is of type text). + block_type (google.cloud.vision_v1p3beta1.types.Block.BlockType): + Detected block type (text, image etc) for + this block. + confidence (float): + Confidence of the OCR results on the block. Range [0, 1]. + """ + class BlockType(proto.Enum): + r"""Type of a block (text, image etc) as identified by OCR. + + Values: + UNKNOWN (0): + Unknown block type. + TEXT (1): + Regular text block. + TABLE (2): + Table block. + PICTURE (3): + Image block. + RULER (4): + Horizontal/vertical line box. + BARCODE (5): + Barcode block. + """ + UNKNOWN = 0 + TEXT = 1 + TABLE = 2 + PICTURE = 3 + RULER = 4 + BARCODE = 5 + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + paragraphs: MutableSequence['Paragraph'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Paragraph', + ) + block_type: BlockType = proto.Field( + proto.ENUM, + number=4, + enum=BlockType, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Paragraph(proto.Message): + r"""Structural unit of text representing a number of words in + certain order. + + Attributes: + property (google.cloud.vision_v1p3beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + paragraph. + bounding_box (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The bounding box for the paragraph. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + words (MutableSequence[google.cloud.vision_v1p3beta1.types.Word]): + List of words in this paragraph. + confidence (float): + Confidence of the OCR results for the paragraph. Range [0, + 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + words: MutableSequence['Word'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Word', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Word(proto.Message): + r"""A word representation. + + Attributes: + property (google.cloud.vision_v1p3beta1.types.TextAnnotation.TextProperty): + Additional information detected for the word. + bounding_box (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The bounding box for the word. The vertices are in the order + of top-left, top-right, bottom-right, bottom-left. When a + rotation of the bounding box is detected the rotation is + represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + symbols (MutableSequence[google.cloud.vision_v1p3beta1.types.Symbol]): + List of symbols in the word. + The order of the symbols follows the natural + reading order. + confidence (float): + Confidence of the OCR results for the word. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + symbols: MutableSequence['Symbol'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Symbol', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Symbol(proto.Message): + r"""A single symbol representation. + + Attributes: + property (google.cloud.vision_v1p3beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + symbol. + bounding_box (google.cloud.vision_v1p3beta1.types.BoundingPoly): + The bounding box for the symbol. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertice order + will still be (0, 1, 2, 3). + text (str): + The actual UTF-8 representation of the + symbol. + confidence (float): + Confidence of the OCR results for the symbol. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + text: str = proto.Field( + proto.STRING, + number=3, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/web_detection.py b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/web_detection.py new file mode 100644 index 00000000..d185f39b --- /dev/null +++ b/owl-bot-staging/v1p3beta1/google/cloud/vision_v1p3beta1/types/web_detection.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p3beta1', + manifest={ + 'WebDetection', + }, +) + + +class WebDetection(proto.Message): + r"""Relevant information for the image from the Internet. + + Attributes: + web_entities (MutableSequence[google.cloud.vision_v1p3beta1.types.WebDetection.WebEntity]): + Deduced entities from similar images on the + Internet. + full_matching_images (MutableSequence[google.cloud.vision_v1p3beta1.types.WebDetection.WebImage]): + Fully matching images from the Internet. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1p3beta1.types.WebDetection.WebImage]): + Partial matching images from the Internet. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + pages_with_matching_images (MutableSequence[google.cloud.vision_v1p3beta1.types.WebDetection.WebPage]): + Web pages containing the matching images from + the Internet. + visually_similar_images (MutableSequence[google.cloud.vision_v1p3beta1.types.WebDetection.WebImage]): + The visually similar image results. + best_guess_labels (MutableSequence[google.cloud.vision_v1p3beta1.types.WebDetection.WebLabel]): + Best guess text labels for the request image. + """ + + class WebEntity(proto.Message): + r"""Entity deduced from similar images on the Internet. + + Attributes: + entity_id (str): + Opaque entity ID. + score (float): + Overall relevancy score for the entity. + Not normalized and not comparable across + different image queries. + description (str): + Canonical description of the entity, in + English. + """ + + entity_id: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + + class WebImage(proto.Message): + r"""Metadata for online images. + + Attributes: + url (str): + The result image URL. + score (float): + (Deprecated) Overall relevancy score for the + image. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class WebPage(proto.Message): + r"""Metadata for web pages. + + Attributes: + url (str): + The result web page URL. + score (float): + (Deprecated) Overall relevancy score for the + web page. + page_title (str): + Title for the web page, may contain HTML + markups. + full_matching_images (MutableSequence[google.cloud.vision_v1p3beta1.types.WebDetection.WebImage]): + Fully matching images on the page. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1p3beta1.types.WebDetection.WebImage]): + Partial matching images on the page. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + page_title: str = proto.Field( + proto.STRING, + number=3, + ) + full_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='WebDetection.WebImage', + ) + partial_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='WebDetection.WebImage', + ) + + class WebLabel(proto.Message): + r"""Label to provide extra metadata for the web detection. + + Attributes: + label (str): + Label for extra metadata. + language_code (str): + The BCP-47 language code for ``label``, such as "en-US" or + "sr-Latn". For more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + """ + + label: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + + web_entities: MutableSequence[WebEntity] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=WebEntity, + ) + full_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=WebImage, + ) + partial_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=WebImage, + ) + pages_with_matching_images: MutableSequence[WebPage] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=WebPage, + ) + visually_similar_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=WebImage, + ) + best_guess_labels: MutableSequence[WebLabel] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=WebLabel, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p3beta1/mypy.ini b/owl-bot-staging/v1p3beta1/mypy.ini new file mode 100644 index 00000000..574c5aed --- /dev/null +++ b/owl-bot-staging/v1p3beta1/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/v1p3beta1/noxfile.py b/owl-bot-staging/v1p3beta1/noxfile.py new file mode 100644 index 00000000..8f218936 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/noxfile.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +import pathlib +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = subprocess.check_output([sys.executable, "setup.py", "--name"], encoding="utf-8") + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.11" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "lint_setup_py", +] + +@nox.session(python=ALL_PYTHON) +def unit(session): + """Run the unit test suite.""" + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.') + + session.run( + 'py.test', + '--quiet', + '--cov=google/cloud/vision_v1p3beta1/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)) + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + session.install( + 'mypy', + 'types-requests', + 'types-protobuf' + ) + session.install('.') + session.run( + 'mypy', + '--explicit-package-bases', + 'google', + ) + + +@nox.session +def update_lower_bounds(session): + """Update lower bounds in constraints.txt to match setup.py""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'update', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + + +@nox.session +def check_lower_bounds(session): + """Check lower bounds in setup.py are reflected in constraints file""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'check', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install("sphinx==7.0.1", "alabaster", "recommonmark") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", BLACK_VERSION) + session.run( + "black", + "--check", + *BLACK_PATHS, + ) + session.run("flake8", "google", "tests", "samples") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *BLACK_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json b/owl-bot-staging/v1p3beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json new file mode 100644 index 00000000..2dae915e --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p3beta1.json @@ -0,0 +1,3293 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.vision.v1p3beta1", + "version": "v1p3beta1" + } + ], + "language": "PYTHON", + "name": "google-cloud-vision", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ImageAnnotatorAsyncClient.async_batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ImageAnnotator.AsyncBatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.AsyncBatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p3beta1.types.AsyncAnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "async_batch_annotate_files" + }, + "description": "Sample for AsyncBatchAnnotateFiles", + "file": "vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ImageAnnotatorClient.async_batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ImageAnnotator.AsyncBatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.AsyncBatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p3beta1.types.AsyncAnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "async_batch_annotate_files" + }, + "description": "Sample for AsyncBatchAnnotateFiles", + "file": "vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ImageAnnotatorAsyncClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p3beta1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1p3beta1_generated_image_annotator_batch_annotate_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ImageAnnotator_BatchAnnotateImages_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_image_annotator_batch_annotate_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ImageAnnotatorClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p3beta1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1p3beta1_generated_image_annotator_batch_annotate_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ImageAnnotator_BatchAnnotateImages_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_image_annotator_batch_annotate_images_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.add_product_to_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.AddProductToProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "AddProductToProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.AddProductToProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "add_product_to_product_set" + }, + "description": "Sample for AddProductToProductSet", + "file": "vision_v1p3beta1_generated_product_search_add_product_to_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_AddProductToProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_add_product_to_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.add_product_to_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.AddProductToProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "AddProductToProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.AddProductToProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "add_product_to_product_set" + }, + "description": "Sample for AddProductToProductSet", + "file": "vision_v1p3beta1_generated_product_search_add_product_to_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_AddProductToProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_add_product_to_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.create_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.CreateProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.CreateProductSetRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1p3beta1.types.ProductSet" + }, + { + "name": "product_set_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ProductSet", + "shortName": "create_product_set" + }, + "description": "Sample for CreateProductSet", + "file": "vision_v1p3beta1_generated_product_search_create_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_CreateProductSet_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_create_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.create_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.CreateProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.CreateProductSetRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1p3beta1.types.ProductSet" + }, + { + "name": "product_set_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ProductSet", + "shortName": "create_product_set" + }, + "description": "Sample for CreateProductSet", + "file": "vision_v1p3beta1_generated_product_search_create_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_CreateProductSet_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_create_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.create_product", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.CreateProduct", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.vision_v1p3beta1.types.Product" + }, + { + "name": "product_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "vision_v1p3beta1_generated_product_search_create_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_CreateProduct_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_create_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.create_product", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.CreateProduct", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.vision_v1p3beta1.types.Product" + }, + { + "name": "product_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "vision_v1p3beta1_generated_product_search_create_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_CreateProduct_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_create_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.create_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.CreateReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.CreateReferenceImageRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "reference_image", + "type": "google.cloud.vision_v1p3beta1.types.ReferenceImage" + }, + { + "name": "reference_image_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ReferenceImage", + "shortName": "create_reference_image" + }, + "description": "Sample for CreateReferenceImage", + "file": "vision_v1p3beta1_generated_product_search_create_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_CreateReferenceImage_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_create_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.create_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.CreateReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.CreateReferenceImageRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "reference_image", + "type": "google.cloud.vision_v1p3beta1.types.ReferenceImage" + }, + { + "name": "reference_image_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ReferenceImage", + "shortName": "create_reference_image" + }, + "description": "Sample for CreateReferenceImage", + "file": "vision_v1p3beta1_generated_product_search_create_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_CreateReferenceImage_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_create_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.delete_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.DeleteProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.DeleteProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product_set" + }, + "description": "Sample for DeleteProductSet", + "file": "vision_v1p3beta1_generated_product_search_delete_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_DeleteProductSet_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_delete_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.delete_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.DeleteProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.DeleteProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product_set" + }, + "description": "Sample for DeleteProductSet", + "file": "vision_v1p3beta1_generated_product_search_delete_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_DeleteProductSet_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_delete_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.delete_product", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.DeleteProduct", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.DeleteProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product" + }, + "description": "Sample for DeleteProduct", + "file": "vision_v1p3beta1_generated_product_search_delete_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_DeleteProduct_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_delete_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.delete_product", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.DeleteProduct", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.DeleteProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product" + }, + "description": "Sample for DeleteProduct", + "file": "vision_v1p3beta1_generated_product_search_delete_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_DeleteProduct_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_delete_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.delete_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.DeleteReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.DeleteReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_reference_image" + }, + "description": "Sample for DeleteReferenceImage", + "file": "vision_v1p3beta1_generated_product_search_delete_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_DeleteReferenceImage_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_delete_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.delete_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.DeleteReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.DeleteReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_reference_image" + }, + "description": "Sample for DeleteReferenceImage", + "file": "vision_v1p3beta1_generated_product_search_delete_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_DeleteReferenceImage_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_delete_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.get_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.GetProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.GetProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ProductSet", + "shortName": "get_product_set" + }, + "description": "Sample for GetProductSet", + "file": "vision_v1p3beta1_generated_product_search_get_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_GetProductSet_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_get_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.get_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.GetProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.GetProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ProductSet", + "shortName": "get_product_set" + }, + "description": "Sample for GetProductSet", + "file": "vision_v1p3beta1_generated_product_search_get_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_GetProductSet_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_get_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.get_product", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.GetProduct", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.GetProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "vision_v1p3beta1_generated_product_search_get_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_GetProduct_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_get_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.get_product", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.GetProduct", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.GetProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "vision_v1p3beta1_generated_product_search_get_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_GetProduct_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_get_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.get_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.GetReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.GetReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ReferenceImage", + "shortName": "get_reference_image" + }, + "description": "Sample for GetReferenceImage", + "file": "vision_v1p3beta1_generated_product_search_get_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_GetReferenceImage_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_get_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.get_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.GetReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.GetReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ReferenceImage", + "shortName": "get_reference_image" + }, + "description": "Sample for GetReferenceImage", + "file": "vision_v1p3beta1_generated_product_search_get_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_GetReferenceImage_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_get_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.import_product_sets", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ImportProductSets", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ImportProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ImportProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "input_config", + "type": "google.cloud.vision_v1p3beta1.types.ImportProductSetsInputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "import_product_sets" + }, + "description": "Sample for ImportProductSets", + "file": "vision_v1p3beta1_generated_product_search_import_product_sets_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ImportProductSets_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_import_product_sets_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.import_product_sets", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ImportProductSets", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ImportProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ImportProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "input_config", + "type": "google.cloud.vision_v1p3beta1.types.ImportProductSetsInputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "import_product_sets" + }, + "description": "Sample for ImportProductSets", + "file": "vision_v1p3beta1_generated_product_search_import_product_sets_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ImportProductSets_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_import_product_sets_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.list_product_sets", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ListProductSets", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ListProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductSetsAsyncPager", + "shortName": "list_product_sets" + }, + "description": "Sample for ListProductSets", + "file": "vision_v1p3beta1_generated_product_search_list_product_sets_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ListProductSets_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_list_product_sets_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.list_product_sets", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ListProductSets", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ListProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductSetsPager", + "shortName": "list_product_sets" + }, + "description": "Sample for ListProductSets", + "file": "vision_v1p3beta1_generated_product_search_list_product_sets_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ListProductSets_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_list_product_sets_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.list_products_in_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ListProductsInProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductsInProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ListProductsInProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductsInProductSetAsyncPager", + "shortName": "list_products_in_product_set" + }, + "description": "Sample for ListProductsInProductSet", + "file": "vision_v1p3beta1_generated_product_search_list_products_in_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ListProductsInProductSet_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_list_products_in_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.list_products_in_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ListProductsInProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductsInProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ListProductsInProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductsInProductSetPager", + "shortName": "list_products_in_product_set" + }, + "description": "Sample for ListProductsInProductSet", + "file": "vision_v1p3beta1_generated_product_search_list_products_in_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ListProductsInProductSet_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_list_products_in_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.list_products", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ListProducts", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ListProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductsAsyncPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "vision_v1p3beta1_generated_product_search_list_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ListProducts_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_list_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.list_products", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ListProducts", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ListProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.services.product_search.pagers.ListProductsPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "vision_v1p3beta1_generated_product_search_list_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ListProducts_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_list_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.list_reference_images", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ListReferenceImages", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListReferenceImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ListReferenceImagesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.services.product_search.pagers.ListReferenceImagesAsyncPager", + "shortName": "list_reference_images" + }, + "description": "Sample for ListReferenceImages", + "file": "vision_v1p3beta1_generated_product_search_list_reference_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ListReferenceImages_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_list_reference_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.list_reference_images", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.ListReferenceImages", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListReferenceImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.ListReferenceImagesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.services.product_search.pagers.ListReferenceImagesPager", + "shortName": "list_reference_images" + }, + "description": "Sample for ListReferenceImages", + "file": "vision_v1p3beta1_generated_product_search_list_reference_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_ListReferenceImages_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_list_reference_images_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.remove_product_from_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.RemoveProductFromProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "RemoveProductFromProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.RemoveProductFromProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "remove_product_from_product_set" + }, + "description": "Sample for RemoveProductFromProductSet", + "file": "vision_v1p3beta1_generated_product_search_remove_product_from_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_RemoveProductFromProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_remove_product_from_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.remove_product_from_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.RemoveProductFromProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "RemoveProductFromProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.RemoveProductFromProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "remove_product_from_product_set" + }, + "description": "Sample for RemoveProductFromProductSet", + "file": "vision_v1p3beta1_generated_product_search_remove_product_from_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_RemoveProductFromProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_remove_product_from_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.update_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.UpdateProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.UpdateProductSetRequest" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1p3beta1.types.ProductSet" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ProductSet", + "shortName": "update_product_set" + }, + "description": "Sample for UpdateProductSet", + "file": "vision_v1p3beta1_generated_product_search_update_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_UpdateProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_update_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.update_product_set", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.UpdateProductSet", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.UpdateProductSetRequest" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1p3beta1.types.ProductSet" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.ProductSet", + "shortName": "update_product_set" + }, + "description": "Sample for UpdateProductSet", + "file": "vision_v1p3beta1_generated_product_search_update_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_UpdateProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_update_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchAsyncClient.update_product", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.UpdateProduct", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.vision_v1p3beta1.types.Product" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "vision_v1p3beta1_generated_product_search_update_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_UpdateProduct_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_update_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p3beta1.ProductSearchClient.update_product", + "method": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch.UpdateProduct", + "service": { + "fullName": "google.cloud.vision.v1p3beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p3beta1.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.vision_v1p3beta1.types.Product" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p3beta1.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "vision_v1p3beta1_generated_product_search_update_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p3beta1_generated_ProductSearch_UpdateProduct_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p3beta1_generated_product_search_update_product_sync.py" + } + ] +} diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_async.py new file mode 100644 index 00000000..5545c720 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p3beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_sync.py new file mode 100644 index 00000000..5f7cde88 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_async_batch_annotate_files_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p3beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_batch_annotate_images_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_batch_annotate_images_async.py new file mode 100644 index 00000000..1e639988 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_batch_annotate_images_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ImageAnnotator_BatchAnnotateImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_batch_annotate_images(): + # Create a client + client = vision_v1p3beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ImageAnnotator_BatchAnnotateImages_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_batch_annotate_images_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_batch_annotate_images_sync.py new file mode 100644 index 00000000..52c2c322 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_image_annotator_batch_annotate_images_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ImageAnnotator_BatchAnnotateImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_batch_annotate_images(): + # Create a client + client = vision_v1p3beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ImageAnnotator_BatchAnnotateImages_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_add_product_to_product_set_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_add_product_to_product_set_async.py new file mode 100644 index 00000000..286211e2 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_add_product_to_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AddProductToProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_AddProductToProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_add_product_to_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.add_product_to_product_set(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_AddProductToProductSet_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_add_product_to_product_set_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_add_product_to_product_set_sync.py new file mode 100644 index 00000000..16790e0e --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_add_product_to_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AddProductToProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_AddProductToProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_add_product_to_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.add_product_to_product_set(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_AddProductToProductSet_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_async.py new file mode 100644 index 00000000..22e7d534 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_CreateProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_create_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_CreateProduct_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_set_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_set_async.py new file mode 100644 index 00000000..670017dc --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_set_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_CreateProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_create_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_CreateProductSet_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_set_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_set_sync.py new file mode 100644 index 00000000..ff5a31e0 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_set_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_CreateProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_create_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_CreateProductSet_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_sync.py new file mode 100644 index 00000000..1e08eefd --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_product_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_CreateProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_create_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_CreateProduct_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_reference_image_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_reference_image_async.py new file mode 100644 index 00000000..faf68e06 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_reference_image_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_CreateReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_create_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + reference_image = vision_v1p3beta1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1p3beta1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = await client.create_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_CreateReferenceImage_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_reference_image_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_reference_image_sync.py new file mode 100644 index 00000000..f9e03b98 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_create_reference_image_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_CreateReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_create_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + reference_image = vision_v1p3beta1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1p3beta1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = client.create_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_CreateReferenceImage_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_async.py new file mode 100644 index 00000000..77d4e37d --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_DeleteProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_delete_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_DeleteProduct_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_set_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_set_async.py new file mode 100644 index 00000000..a16b06dc --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_set_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_DeleteProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_delete_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + await client.delete_product_set(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_DeleteProductSet_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_set_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_set_sync.py new file mode 100644 index 00000000..f69773f1 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_set_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_DeleteProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_delete_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + client.delete_product_set(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_DeleteProductSet_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_sync.py new file mode 100644 index 00000000..7d46d993 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_product_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_DeleteProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_delete_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_DeleteProduct_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_reference_image_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_reference_image_async.py new file mode 100644 index 00000000..0b0ea28c --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_reference_image_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_DeleteReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_delete_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + await client.delete_reference_image(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_DeleteReferenceImage_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_reference_image_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_reference_image_sync.py new file mode 100644 index 00000000..440e98b7 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_delete_reference_image_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_DeleteReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_delete_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + client.delete_reference_image(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_DeleteReferenceImage_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_async.py new file mode 100644 index 00000000..cb9bf023 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_GetProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_get_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_GetProduct_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_set_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_set_async.py new file mode 100644 index 00000000..fc7ef6ac --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_set_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_GetProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_get_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_GetProductSet_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_set_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_set_sync.py new file mode 100644 index 00000000..b2504879 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_set_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_GetProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_get_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = client.get_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_GetProductSet_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_sync.py new file mode 100644 index 00000000..2249974b --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_product_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_GetProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_get_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_GetProduct_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_reference_image_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_reference_image_async.py new file mode 100644 index 00000000..99d19fe9 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_reference_image_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_GetReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_get_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = await client.get_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_GetReferenceImage_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_reference_image_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_reference_image_sync.py new file mode 100644 index 00000000..4261b0c7 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_get_reference_image_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_GetReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_get_reference_image(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = client.get_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_GetReferenceImage_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_import_product_sets_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_import_product_sets_async.py new file mode 100644 index 00000000..b10ad3fd --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_import_product_sets_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ImportProductSets_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_import_product_sets(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ImportProductSets_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_import_product_sets_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_import_product_sets_sync.py new file mode 100644 index 00000000..0c17b20a --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_import_product_sets_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ImportProductSets_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_import_product_sets(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ImportProductSets_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_product_sets_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_product_sets_async.py new file mode 100644 index 00000000..0c5253df --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_product_sets_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ListProductSets_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_list_product_sets(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ListProductSets_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_product_sets_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_product_sets_sync.py new file mode 100644 index 00000000..ce22614f --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_product_sets_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ListProductSets_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_list_product_sets(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ListProductSets_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_async.py new file mode 100644 index 00000000..4f92b704 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ListProducts_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_list_products(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ListProducts_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_in_product_set_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_in_product_set_async.py new file mode 100644 index 00000000..36a25e41 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_in_product_set_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductsInProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ListProductsInProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_list_products_in_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ListProductsInProductSet_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_in_product_set_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_in_product_set_sync.py new file mode 100644 index 00000000..30f382ff --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_in_product_set_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductsInProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ListProductsInProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_list_products_in_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ListProductsInProductSet_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_sync.py new file mode 100644 index 00000000..029f259f --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_products_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ListProducts_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_list_products(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ListProducts_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_reference_images_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_reference_images_async.py new file mode 100644 index 00000000..0c4c6dc3 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_reference_images_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListReferenceImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ListReferenceImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_list_reference_images(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ListReferenceImages_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_reference_images_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_reference_images_sync.py new file mode 100644 index 00000000..1e0915b3 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_list_reference_images_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListReferenceImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_ListReferenceImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_list_reference_images(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_ListReferenceImages_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_remove_product_from_product_set_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_remove_product_from_product_set_async.py new file mode 100644 index 00000000..a617d873 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_remove_product_from_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RemoveProductFromProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_RemoveProductFromProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.remove_product_from_product_set(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_RemoveProductFromProductSet_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_remove_product_from_product_set_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_remove_product_from_product_set_sync.py new file mode 100644 index 00000000..52d6dede --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_remove_product_from_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RemoveProductFromProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_RemoveProductFromProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.remove_product_from_product_set(request=request) + + +# [END vision_v1p3beta1_generated_ProductSearch_RemoveProductFromProductSet_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_async.py new file mode 100644 index 00000000..a6d4552f --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_UpdateProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_update_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.UpdateProductRequest( + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_UpdateProduct_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_set_async.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_set_async.py new file mode 100644 index 00000000..720a8159 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_UpdateProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +async def sample_update_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.UpdateProductSetRequest( + ) + + # Make the request + response = await client.update_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_UpdateProductSet_async] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_set_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_set_sync.py new file mode 100644 index 00000000..9cc12aa1 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_UpdateProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_update_product_set(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.UpdateProductSetRequest( + ) + + # Make the request + response = client.update_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_UpdateProductSet_sync] diff --git a/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_sync.py b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_sync.py new file mode 100644 index 00000000..037bf537 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/samples/generated_samples/vision_v1p3beta1_generated_product_search_update_product_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p3beta1_generated_ProductSearch_UpdateProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p3beta1 + + +def sample_update_product(): + # Create a client + client = vision_v1p3beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p3beta1.UpdateProductRequest( + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p3beta1_generated_ProductSearch_UpdateProduct_sync] diff --git a/owl-bot-staging/v1p3beta1/scripts/fixup_vision_v1p3beta1_keywords.py b/owl-bot-staging/v1p3beta1/scripts/fixup_vision_v1p3beta1_keywords.py new file mode 100644 index 00000000..c3f4c55d --- /dev/null +++ b/owl-bot-staging/v1p3beta1/scripts/fixup_vision_v1p3beta1_keywords.py @@ -0,0 +1,195 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class visionCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'add_product_to_product_set': ('name', 'product', ), + 'async_batch_annotate_files': ('requests', ), + 'batch_annotate_images': ('requests', ), + 'create_product': ('parent', 'product', 'product_id', ), + 'create_product_set': ('parent', 'product_set', 'product_set_id', ), + 'create_reference_image': ('parent', 'reference_image', 'reference_image_id', ), + 'delete_product': ('name', ), + 'delete_product_set': ('name', ), + 'delete_reference_image': ('name', ), + 'get_product': ('name', ), + 'get_product_set': ('name', ), + 'get_reference_image': ('name', ), + 'import_product_sets': ('parent', 'input_config', ), + 'list_products': ('parent', 'page_size', 'page_token', ), + 'list_product_sets': ('parent', 'page_size', 'page_token', ), + 'list_products_in_product_set': ('name', 'page_size', 'page_token', ), + 'list_reference_images': ('parent', 'page_size', 'page_token', ), + 'remove_product_from_product_set': ('name', 'product', ), + 'update_product': ('product', 'update_mask', ), + 'update_product_set': ('product_set', 'update_mask', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=visionCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the vision client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/owl-bot-staging/v1p3beta1/setup.py b/owl-bot-staging/v1p3beta1/setup.py new file mode 100644 index 00000000..7525c907 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/setup.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import io +import os + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-cloud-vision' + + +description = "Google Cloud Vision API client library" + +version = {} +with open(os.path.join(package_root, 'google/cloud/vision/gapic_version.py')) as fp: + exec(fp.read(), version) +version = version["__version__"] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.0, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "proto-plus >= 1.22.0, <2.0.0dev", + "proto-plus >= 1.22.2, <2.0.0dev; python_version>='3.11'", + "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/python-vision" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.PEP420PackageFinder.find() + if package.startswith("google") +] + +namespaces = ["google", "google.cloud"] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + namespace_packages=namespaces, + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/v1p3beta1/testing/constraints-3.10.txt b/owl-bot-staging/v1p3beta1/testing/constraints-3.10.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p3beta1/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p3beta1/testing/constraints-3.11.txt b/owl-bot-staging/v1p3beta1/testing/constraints-3.11.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p3beta1/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p3beta1/testing/constraints-3.12.txt b/owl-bot-staging/v1p3beta1/testing/constraints-3.12.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p3beta1/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p3beta1/testing/constraints-3.7.txt b/owl-bot-staging/v1p3beta1/testing/constraints-3.7.txt new file mode 100644 index 00000000..6c44adfe --- /dev/null +++ b/owl-bot-staging/v1p3beta1/testing/constraints-3.7.txt @@ -0,0 +1,9 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file. +# Pin the version to the lower bound. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", +# Then this file should have google-cloud-foo==1.14.0 +google-api-core==1.34.0 +proto-plus==1.22.0 +protobuf==3.19.5 diff --git a/owl-bot-staging/v1p3beta1/testing/constraints-3.8.txt b/owl-bot-staging/v1p3beta1/testing/constraints-3.8.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p3beta1/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p3beta1/testing/constraints-3.9.txt b/owl-bot-staging/v1p3beta1/testing/constraints-3.9.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p3beta1/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p3beta1/tests/__init__.py b/owl-bot-staging/v1p3beta1/tests/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p3beta1/tests/unit/__init__.py b/owl-bot-staging/v1p3beta1/tests/unit/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p3beta1/tests/unit/gapic/__init__.py b/owl-bot-staging/v1p3beta1/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/__init__.py b/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/test_image_annotator.py b/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/test_image_annotator.py new file mode 100644 index 00000000..3b9be28f --- /dev/null +++ b/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/test_image_annotator.py @@ -0,0 +1,2095 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule +from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.vision_v1p3beta1.services.image_annotator import ImageAnnotatorAsyncClient +from google.cloud.vision_v1p3beta1.services.image_annotator import ImageAnnotatorClient +from google.cloud.vision_v1p3beta1.services.image_annotator import transports +from google.cloud.vision_v1p3beta1.types import geometry +from google.cloud.vision_v1p3beta1.types import image_annotator +from google.cloud.vision_v1p3beta1.types import product_search +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.type import latlng_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ImageAnnotatorClient._get_default_mtls_endpoint(None) is None + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ImageAnnotatorGrpcTransport, "grpc"), + (transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +def test_image_annotator_client_get_transport_class(): + transport = ImageAnnotatorClient.get_transport_class() + available_transports = [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorRestTransport, + ] + assert transport in available_transports + + transport = ImageAnnotatorClient.get_transport_class("grpc") + assert transport == transports.ImageAnnotatorGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "true"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "false"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "false"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_image_annotator_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + ImageAnnotatorClient, ImageAnnotatorAsyncClient +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", None), +]) +def test_image_annotator_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_image_annotator_client_client_options_from_dict(): + with mock.patch('google.cloud.vision_v1p3beta1.services.image_annotator.transports.ImageAnnotatorGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ImageAnnotatorClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_image_annotator_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=None, + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse( + ) + response = client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + client.batch_annotate_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + +@pytest.mark.asyncio +async def test_batch_annotate_images_async(transport: str = 'grpc_asyncio', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse( + )) + response = await client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +@pytest.mark.asyncio +async def test_batch_annotate_images_async_from_dict(): + await test_batch_annotate_images_async(request_type=dict) + + +def test_batch_annotate_images_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + + +def test_batch_annotate_images_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateFilesRequest, + dict, +]) +def test_async_batch_annotate_files(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.async_batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_async_batch_annotate_files_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + client.async_batch_annotate_files() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_async(transport: str = 'grpc_asyncio', request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.async_batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_async_from_dict(): + await test_async_batch_annotate_files_async(request_type=dict) + + +def test_async_batch_annotate_files_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.async_batch_annotate_files( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + + +def test_async_batch_annotate_files_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.async_batch_annotate_files( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_annotate_images(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_rest_required_fields(request_type=image_annotator.BatchAnnotateImagesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_annotate_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_annotate_images_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_annotate_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_annotate_images_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_batch_annotate_images") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_batch_annotate_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.BatchAnnotateImagesRequest.pb(image_annotator.BatchAnnotateImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = image_annotator.BatchAnnotateImagesResponse.to_json(image_annotator.BatchAnnotateImagesResponse()) + + request = image_annotator.BatchAnnotateImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = image_annotator.BatchAnnotateImagesResponse() + + client.batch_annotate_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_annotate_images_rest_bad_request(transport: str = 'rest', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.batch_annotate_images(request) + + +def test_batch_annotate_images_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_annotate_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/images:annotate" % client.transport._host, args[1]) + + +def test_batch_annotate_images_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +def test_batch_annotate_images_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateFilesRequest, + dict, +]) +def test_async_batch_annotate_files_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.async_batch_annotate_files(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_async_batch_annotate_files_rest_required_fields(request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.async_batch_annotate_files(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_async_batch_annotate_files_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.async_batch_annotate_files._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_async_batch_annotate_files_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_async_batch_annotate_files") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_async_batch_annotate_files") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.AsyncBatchAnnotateFilesRequest.pb(image_annotator.AsyncBatchAnnotateFilesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = image_annotator.AsyncBatchAnnotateFilesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.async_batch_annotate_files(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_async_batch_annotate_files_rest_bad_request(transport: str = 'rest', request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.async_batch_annotate_files(request) + + +def test_async_batch_annotate_files_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.async_batch_annotate_files(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/files:asyncBatchAnnotate" % client.transport._host, args[1]) + + +def test_async_batch_annotate_files_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +def test_async_batch_annotate_files_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ImageAnnotatorClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "rest", +]) +def test_transport_kind(transport_name): + transport = ImageAnnotatorClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ImageAnnotatorGrpcTransport, + ) + +def test_image_annotator_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_image_annotator_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.vision_v1p3beta1.services.image_annotator.transports.ImageAnnotatorTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'batch_annotate_images', + 'async_batch_annotate_files', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_image_annotator_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.vision_v1p3beta1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id="octopus", + ) + + +def test_image_annotator_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.vision_v1p3beta1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport() + adc.assert_called_once() + + +def test_image_annotator_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ImageAnnotatorClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + ], +) +def test_image_annotator_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-vision',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, + ], +) +def test_image_annotator_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ImageAnnotatorGrpcTransport, grpc_helpers), + (transports.ImageAnnotatorGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_image_annotator_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=["1", "2"], + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_image_annotator_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel") as mock_configure_mtls_channel: + transports.ImageAnnotatorRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_image_annotator_rest_lro_client(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_no_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_with_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_image_annotator_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ImageAnnotatorClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ImageAnnotatorClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.batch_annotate_images._session + session2 = client2.transport.batch_annotate_images._session + assert session1 != session2 + session1 = client1.transport.async_batch_annotate_files._session + session2 = client2.transport.async_batch_annotate_files._session + assert session1 != session2 +def test_image_annotator_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_image_annotator_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_image_annotator_grpc_lro_client(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_image_annotator_grpc_lro_async_client(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_path(): + project = "squid" + location = "clam" + product = "whelk" + expected = "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + actual = ImageAnnotatorClient.product_path(project, location, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "octopus", + "location": "oyster", + "product": "nudibranch", + } + path = ImageAnnotatorClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_product_path(path) + assert expected == actual + +def test_product_set_path(): + project = "cuttlefish" + location = "mussel" + product_set = "winkle" + expected = "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + actual = ImageAnnotatorClient.product_set_path(project, location, product_set) + assert expected == actual + + +def test_parse_product_set_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "product_set": "abalone", + } + path = ImageAnnotatorClient.product_set_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_product_set_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ImageAnnotatorClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = ImageAnnotatorClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder, ) + actual = ImageAnnotatorClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = ImageAnnotatorClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ImageAnnotatorClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = ImageAnnotatorClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project, ) + actual = ImageAnnotatorClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = ImageAnnotatorClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ImageAnnotatorClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = ImageAnnotatorClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + transport_class = ImageAnnotatorClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/test_product_search.py b/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/test_product_search.py new file mode 100644 index 00000000..24a62b75 --- /dev/null +++ b/owl-bot-staging/v1p3beta1/tests/unit/gapic/vision_v1p3beta1/test_product_search.py @@ -0,0 +1,11247 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule +from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.vision_v1p3beta1.services.product_search import ProductSearchAsyncClient +from google.cloud.vision_v1p3beta1.services.product_search import ProductSearchClient +from google.cloud.vision_v1p3beta1.services.product_search import pagers +from google.cloud.vision_v1p3beta1.services.product_search import transports +from google.cloud.vision_v1p3beta1.types import geometry +from google.cloud.vision_v1p3beta1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ProductSearchClient._get_default_mtls_endpoint(None) is None + assert ProductSearchClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductSearchClient, "grpc"), + (ProductSearchAsyncClient, "grpc_asyncio"), + (ProductSearchClient, "rest"), +]) +def test_product_search_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ProductSearchGrpcTransport, "grpc"), + (transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ProductSearchRestTransport, "rest"), +]) +def test_product_search_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductSearchClient, "grpc"), + (ProductSearchAsyncClient, "grpc_asyncio"), + (ProductSearchClient, "rest"), +]) +def test_product_search_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +def test_product_search_client_get_transport_class(): + transport = ProductSearchClient.get_transport_class() + available_transports = [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchRestTransport, + ] + assert transport in available_transports + + transport = ProductSearchClient.get_transport_class("grpc") + assert transport == transports.ProductSearchGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest"), +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +def test_product_search_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ProductSearchClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ProductSearchClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", "true"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", "false"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", "true"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", "false"), +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_product_search_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + ProductSearchClient, ProductSearchAsyncClient +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +def test_product_search_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest"), +]) +def test_product_search_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", grpc_helpers), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", None), +]) +def test_product_search_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_product_search_client_client_options_from_dict(): + with mock.patch('google.cloud.vision_v1p3beta1.services.product_search.transports.ProductSearchGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ProductSearchClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", grpc_helpers), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_product_search_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=None, + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductSetRequest, + dict, +]) +def test_create_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_create_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + client.create_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + +@pytest.mark.asyncio +async def test_create_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_create_product_set_async_from_dict(): + await test_create_product_set_async(request_type=dict) + + +def test_create_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductSetRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductSetRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_product_set( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].product_set_id + mock_val = 'product_set_id_value' + assert arg == mock_val + + +def test_create_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_product_set( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].product_set_id + mock_val = 'product_set_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductSetsRequest, + dict, +]) +def test_list_product_sets(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_product_sets_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + client.list_product_sets() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + +@pytest.mark.asyncio +async def test_list_product_sets_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductSetsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_product_sets_async_from_dict(): + await test_list_product_sets_async(request_type=dict) + + +def test_list_product_sets_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + call.return_value = product_search_service.ListProductSetsResponse() + client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_product_sets_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse()) + await client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_product_sets_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_product_sets( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_product_sets_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_product_sets_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_product_sets( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_product_sets_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + + +def test_list_product_sets_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_product_sets(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in results) +def test_list_product_sets_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + pages = list(client.list_product_sets(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_product_sets_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_product_sets(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_product_sets_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_product_sets(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductSetRequest, + dict, +]) +def test_get_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_get_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + client.get_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + +@pytest.mark.asyncio +async def test_get_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_get_product_set_async_from_dict(): + await test_get_product_set_async(request_type=dict) + + +def test_get_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductSetRequest, + dict, +]) +def test_update_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + client.update_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + +@pytest.mark.asyncio +async def test_update_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.UpdateProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_update_product_set_async_from_dict(): + await test_update_product_set_async(request_type=dict) + + +def test_update_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductSetRequest() + + request.product_set.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product_set.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductSetRequest() + + request.product_set.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product_set.name=name_value', + ) in kw['metadata'] + + +def test_update_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product_set( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_update_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_product_set( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_update_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductSetRequest, + dict, +]) +def test_delete_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + client.delete_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + +@pytest.mark.asyncio +async def test_delete_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_product_set_async_from_dict(): + await test_delete_product_set_async(request_type=dict) + + +def test_delete_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + call.return_value = None + client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductRequest, + dict, +]) +def test_create_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_create_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + client.create_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + +@pytest.mark.asyncio +async def test_create_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_create_product_async_from_dict(): + await test_create_product_async(request_type=dict) + + +def test_create_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_product( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].product_id + mock_val = 'product_id_value' + assert arg == mock_val + + +def test_create_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_product( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].product_id + mock_val = 'product_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsRequest, + dict, +]) +def test_list_products(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + client.list_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + +@pytest.mark.asyncio +async def test_list_products_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_products_async_from_dict(): + await test_list_products_async(request_type=dict) + + +def test_list_products_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + call.return_value = product_search_service.ListProductsResponse() + client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_products_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse()) + await client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_products_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_products_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_products_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_products_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_products(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) +def test_list_products_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = list(client.list_products(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_products_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_products(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_products(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductRequest, + dict, +]) +def test_get_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_get_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + client.get_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + +@pytest.mark.asyncio +async def test_get_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_get_product_async_from_dict(): + await test_get_product_async(request_type=dict) + + +def test_get_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductRequest, + dict, +]) +def test_update_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_update_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + client.update_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + +@pytest.mark.asyncio +async def test_update_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.UpdateProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_update_product_async_from_dict(): + await test_update_product_async(request_type=dict) + + +def test_update_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductRequest() + + request.product.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductRequest() + + request.product.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product.name=name_value', + ) in kw['metadata'] + + +def test_update_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_update_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_product( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_update_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductRequest, + dict, +]) +def test_delete_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + client.delete_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + +@pytest.mark.asyncio +async def test_delete_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_product_async_from_dict(): + await test_delete_product_async(request_type=dict) + + +def test_delete_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + call.return_value = None + client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateReferenceImageRequest, + dict, +]) +def test_create_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + response = client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_create_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + client.create_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + +@pytest.mark.asyncio +async def test_create_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + )) + response = await client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +@pytest.mark.asyncio +async def test_create_reference_image_async_from_dict(): + await test_create_reference_image_async(request_type=dict) + + +def test_create_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateReferenceImageRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + call.return_value = product_search_service.ReferenceImage() + client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateReferenceImageRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + await client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_reference_image( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].reference_image + mock_val = product_search_service.ReferenceImage(name='name_value') + assert arg == mock_val + arg = args[0].reference_image_id + mock_val = 'reference_image_id_value' + assert arg == mock_val + + +def test_create_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + +@pytest.mark.asyncio +async def test_create_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_reference_image( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].reference_image + mock_val = product_search_service.ReferenceImage(name='name_value') + assert arg == mock_val + arg = args[0].reference_image_id + mock_val = 'reference_image_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteReferenceImageRequest, + dict, +]) +def test_delete_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + client.delete_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + +@pytest.mark.asyncio +async def test_delete_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_reference_image_async_from_dict(): + await test_delete_reference_image_async(request_type=dict) + + +def test_delete_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + call.return_value = None + client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListReferenceImagesRequest, + dict, +]) +def test_list_reference_images(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + ) + response = client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +def test_list_reference_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + client.list_reference_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + +@pytest.mark.asyncio +async def test_list_reference_images_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListReferenceImagesRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + )) + response = await client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesAsyncPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_reference_images_async_from_dict(): + await test_list_reference_images_async(request_type=dict) + + +def test_list_reference_images_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListReferenceImagesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + call.return_value = product_search_service.ListReferenceImagesResponse() + client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_reference_images_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListReferenceImagesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse()) + await client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_reference_images_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_reference_images( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_reference_images_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_reference_images_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_reference_images( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_reference_images_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + + +def test_list_reference_images_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_reference_images(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in results) +def test_list_reference_images_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + pages = list(client.list_reference_images(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_reference_images_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_reference_images(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_reference_images_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_reference_images(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetReferenceImageRequest, + dict, +]) +def test_get_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + response = client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_get_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + client.get_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + +@pytest.mark.asyncio +async def test_get_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + )) + response = await client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +@pytest.mark.asyncio +async def test_get_reference_image_async_from_dict(): + await test_get_reference_image_async(request_type=dict) + + +def test_get_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + call.return_value = product_search_service.ReferenceImage() + client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + await client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.AddProductToProductSetRequest, + dict, +]) +def test_add_product_to_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_add_product_to_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + client.add_product_to_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + +@pytest.mark.asyncio +async def test_add_product_to_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.AddProductToProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_add_product_to_product_set_async_from_dict(): + await test_add_product_to_product_set_async(request_type=dict) + + +def test_add_product_to_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.AddProductToProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + call.return_value = None + client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_product_to_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.AddProductToProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_add_product_to_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.add_product_to_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_product_to_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_product_to_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.add_product_to_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_product_to_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.RemoveProductFromProductSetRequest, + dict, +]) +def test_remove_product_from_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_remove_product_from_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + client.remove_product_from_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.RemoveProductFromProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_async_from_dict(): + await test_remove_product_from_product_set_async(request_type=dict) + + +def test_remove_product_from_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.RemoveProductFromProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + call.return_value = None + client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.RemoveProductFromProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_remove_product_from_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.remove_product_from_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_product_from_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.remove_product_from_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsInProductSetRequest, + dict, +]) +def test_list_products_in_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + ) + response = client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_in_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + client.list_products_in_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductsInProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_from_dict(): + await test_list_products_in_product_set_async(request_type=dict) + + +def test_list_products_in_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsInProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + call.return_value = product_search_service.ListProductsInProductSetResponse() + client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsInProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse()) + await client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_list_products_in_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_products_in_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_list_products_in_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_list_products_in_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_products_in_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_products_in_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + + +def test_list_products_in_product_set_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('name', ''), + )), + ) + pager = client.list_products_in_product_set(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) +def test_list_products_in_product_set_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = list(client.list_products_in_product_set(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_products_in_product_set(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_products_in_product_set(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.ImportProductSetsRequest, + dict, +]) +def test_import_product_sets(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_product_sets_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + client.import_product_sets() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + +@pytest.mark.asyncio +async def test_import_product_sets_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ImportProductSetsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_product_sets_async_from_dict(): + await test_import_product_sets_async(request_type=dict) + + +def test_import_product_sets_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ImportProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_import_product_sets_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ImportProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_import_product_sets_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.import_product_sets( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].input_config + mock_val = product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')) + assert arg == mock_val + + +def test_import_product_sets_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + +@pytest.mark.asyncio +async def test_import_product_sets_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.import_product_sets( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].input_config + mock_val = product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_import_product_sets_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductSetRequest, + dict, +]) +def test_create_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request_init["product_set"] = {'name': 'name_value', 'display_name': 'display_name_value', 'index_time': {'seconds': 751, 'nanos': 543}, 'index_error': {'code': 411, 'message': 'message_value', 'details': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}]}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateProductSetRequest.meta.fields["product_set"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product_set"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product_set"][field])): + del request_init["product_set"][field][i][subfield] + else: + del request_init["product_set"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_create_product_set_rest_required_fields(request_type=product_search_service.CreateProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("product_set_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productSetId", )) & set(("parent", "productSet", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateProductSetRequest.pb(product_search_service.CreateProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.CreateProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.create_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_product_set(request) + + +def test_create_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{parent=projects/*/locations/*}/productSets" % client.transport._host, args[1]) + + +def test_create_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + +def test_create_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductSetsRequest, + dict, +]) +def test_list_product_sets_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_product_sets(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_product_sets_rest_required_fields(request_type=product_search_service.ListProductSetsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_product_sets._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_product_sets(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_product_sets_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_product_sets._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_product_sets_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_product_sets") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_product_sets") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductSetsRequest.pb(product_search_service.ListProductSetsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductSetsResponse.to_json(product_search_service.ListProductSetsResponse()) + + request = product_search_service.ListProductSetsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductSetsResponse() + + client.list_product_sets(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_product_sets_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductSetsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_product_sets(request) + + +def test_list_product_sets_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_product_sets(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{parent=projects/*/locations/*}/productSets" % client.transport._host, args[1]) + + +def test_list_product_sets_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + + +def test_list_product_sets_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductSetsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + pager = client.list_product_sets(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in results) + + pages = list(client.list_product_sets(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductSetRequest, + dict, +]) +def test_get_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_get_product_set_rest_required_fields(request_type=product_search_service.GetProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetProductSetRequest.pb(product_search_service.GetProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.GetProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.get_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_product_set(request) + + +def test_get_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_get_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + + +def test_get_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductSetRequest, + dict, +]) +def test_update_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + request_init["product_set"] = {'name': 'projects/sample1/locations/sample2/productSets/sample3', 'display_name': 'display_name_value', 'index_time': {'seconds': 751, 'nanos': 543}, 'index_error': {'code': 411, 'message': 'message_value', 'details': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}]}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.UpdateProductSetRequest.meta.fields["product_set"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product_set"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product_set"][field])): + del request_init["product_set"][field][i][subfield] + else: + del request_init["product_set"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_product_set_rest_required_fields(request_type=product_search_service.UpdateProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "patch", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("productSet", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_update_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_update_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.UpdateProductSetRequest.pb(product_search_service.UpdateProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.UpdateProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.update_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.UpdateProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_product_set(request) + + +def test_update_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{product_set.name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_update_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductSetRequest, + dict, +]) +def test_delete_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_set_rest_required_fields(request_type=product_search_service.DeleteProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteProductSetRequest.pb(product_search_service.DeleteProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_product_set(request) + + +def test_delete_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_delete_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + + +def test_delete_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductRequest, + dict, +]) +def test_create_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request_init["product"] = {'name': 'name_value', 'display_name': 'display_name_value', 'description': 'description_value', 'product_category': 'product_category_value', 'product_labels': [{'key': 'key_value', 'value': 'value_value'}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateProductRequest.meta.fields["product"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product"][field])): + del request_init["product"][field][i][subfield] + else: + del request_init["product"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_create_product_rest_required_fields(request_type=product_search_service.CreateProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("product_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productId", )) & set(("parent", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateProductRequest.pb(product_search_service.CreateProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.CreateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.create_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_product(request) + + +def test_create_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{parent=projects/*/locations/*}/products" % client.transport._host, args[1]) + + +def test_create_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + +def test_create_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsRequest, + dict, +]) +def test_list_products_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_products(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_rest_required_fields(request_type=product_search_service.ListProductsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_products(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_products_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_products") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductsRequest.pb(product_search_service.ListProductsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductsResponse.to_json(product_search_service.ListProductsResponse()) + + request = product_search_service.ListProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductsResponse() + + client.list_products(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_products_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_products(request) + + +def test_list_products_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_products(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{parent=projects/*/locations/*}/products" % client.transport._host, args[1]) + + +def test_list_products_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + pager = client.list_products(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) + + pages = list(client.list_products(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductRequest, + dict, +]) +def test_get_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_get_product_rest_required_fields(request_type=product_search_service.GetProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetProductRequest.pb(product_search_service.GetProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.GetProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.get_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_product(request) + + +def test_get_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_get_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + + +def test_get_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductRequest, + dict, +]) +def test_update_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + request_init["product"] = {'name': 'projects/sample1/locations/sample2/products/sample3', 'display_name': 'display_name_value', 'description': 'description_value', 'product_category': 'product_category_value', 'product_labels': [{'key': 'key_value', 'value': 'value_value'}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.UpdateProductRequest.meta.fields["product"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product"][field])): + del request_init["product"][field][i][subfield] + else: + del request_init["product"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_update_product_rest_required_fields(request_type=product_search_service.UpdateProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "patch", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_update_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_update_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.UpdateProductRequest.pb(product_search_service.UpdateProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.UpdateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.update_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.UpdateProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_product(request) + + +def test_update_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{product.name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_update_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductRequest, + dict, +]) +def test_delete_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_product(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_rest_required_fields(request_type=product_search_service.DeleteProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_product") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteProductRequest.pb(product_search_service.DeleteProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_product(request) + + +def test_delete_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_delete_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + + +def test_delete_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateReferenceImageRequest, + dict, +]) +def test_create_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request_init["reference_image"] = {'name': 'name_value', 'uri': 'uri_value', 'bounding_polys': [{'vertices': [{'x': 120, 'y': 121}], 'normalized_vertices': [{'x': 0.12, 'y': 0.121}]}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateReferenceImageRequest.meta.fields["reference_image"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["reference_image"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["reference_image"][field])): + del request_init["reference_image"][field][i][subfield] + else: + del request_init["reference_image"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_reference_image(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_create_reference_image_rest_required_fields(request_type=product_search_service.CreateReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_reference_image._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("reference_image_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(("referenceImageId", )) & set(("parent", "referenceImage", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_reference_image") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_reference_image") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateReferenceImageRequest.pb(product_search_service.CreateReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ReferenceImage.to_json(product_search_service.ReferenceImage()) + + request = product_search_service.CreateReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ReferenceImage() + + client.create_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_reference_image(request) + + +def test_create_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages" % client.transport._host, args[1]) + + +def test_create_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + +def test_create_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteReferenceImageRequest, + dict, +]) +def test_delete_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_reference_image(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_reference_image_rest_required_fields(request_type=product_search_service.DeleteReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_reference_image") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteReferenceImageRequest.pb(product_search_service.DeleteReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_reference_image(request) + + +def test_delete_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}" % client.transport._host, args[1]) + + +def test_delete_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + + +def test_delete_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListReferenceImagesRequest, + dict, +]) +def test_list_reference_images_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_reference_images(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +def test_list_reference_images_rest_required_fields(request_type=product_search_service.ListReferenceImagesRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_reference_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_reference_images._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_reference_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_reference_images_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_reference_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_reference_images_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_reference_images") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_reference_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListReferenceImagesRequest.pb(product_search_service.ListReferenceImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListReferenceImagesResponse.to_json(product_search_service.ListReferenceImagesResponse()) + + request = product_search_service.ListReferenceImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListReferenceImagesResponse() + + client.list_reference_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_reference_images_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListReferenceImagesRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_reference_images(request) + + +def test_list_reference_images_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_reference_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{parent=projects/*/locations/*/products/*}/referenceImages" % client.transport._host, args[1]) + + +def test_list_reference_images_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + + +def test_list_reference_images_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListReferenceImagesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + pager = client.list_reference_images(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in results) + + pages = list(client.list_reference_images(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetReferenceImageRequest, + dict, +]) +def test_get_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_reference_image(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_get_reference_image_rest_required_fields(request_type=product_search_service.GetReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_reference_image") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_reference_image") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetReferenceImageRequest.pb(product_search_service.GetReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ReferenceImage.to_json(product_search_service.ReferenceImage()) + + request = product_search_service.GetReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ReferenceImage() + + client.get_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_reference_image(request) + + +def test_get_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/products/*/referenceImages/*}" % client.transport._host, args[1]) + + +def test_get_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + + +def test_get_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.AddProductToProductSetRequest, + dict, +]) +def test_add_product_to_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_product_to_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_add_product_to_product_set_rest_required_fields(request_type=product_search_service.AddProductToProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request_init["product"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_product_to_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_product_to_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_product_to_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_product_to_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_product_to_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_product_to_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_add_product_to_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.AddProductToProductSetRequest.pb(product_search_service.AddProductToProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.AddProductToProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.add_product_to_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_add_product_to_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.AddProductToProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.add_product_to_product_set(request) + + +def test_add_product_to_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + product='product_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_product_to_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/productSets/*}:addProduct" % client.transport._host, args[1]) + + +def test_add_product_to_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + + +def test_add_product_to_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.RemoveProductFromProductSetRequest, + dict, +]) +def test_remove_product_from_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_product_from_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_remove_product_from_product_set_rest_required_fields(request_type=product_search_service.RemoveProductFromProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request_init["product"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_product_from_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_product_from_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_product_from_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_product_from_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_product_from_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_product_from_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_remove_product_from_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.RemoveProductFromProductSetRequest.pb(product_search_service.RemoveProductFromProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.RemoveProductFromProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.remove_product_from_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_remove_product_from_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.RemoveProductFromProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.remove_product_from_product_set(request) + + +def test_remove_product_from_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + product='product_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_product_from_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/productSets/*}:removeProduct" % client.transport._host, args[1]) + + +def test_remove_product_from_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + + +def test_remove_product_from_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsInProductSetRequest, + dict, +]) +def test_list_products_in_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_products_in_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_in_product_set_rest_required_fields(request_type=product_search_service.ListProductsInProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products_in_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products_in_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_products_in_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_products_in_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products_in_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_in_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_products_in_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_products_in_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductsInProductSetRequest.pb(product_search_service.ListProductsInProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductsInProductSetResponse.to_json(product_search_service.ListProductsInProductSetResponse()) + + request = product_search_service.ListProductsInProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductsInProductSetResponse() + + client.list_products_in_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_products_in_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductsInProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_products_in_product_set(request) + + +def test_list_products_in_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_products_in_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{name=projects/*/locations/*/productSets/*}/products" % client.transport._host, args[1]) + + +def test_list_products_in_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + + +def test_list_products_in_product_set_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductsInProductSetResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + pager = client.list_products_in_product_set(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) + + pages = list(client.list_products_in_product_set(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ImportProductSetsRequest, + dict, +]) +def test_import_product_sets_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.import_product_sets(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_product_sets_rest_required_fields(request_type=product_search_service.ImportProductSetsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).import_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).import_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.import_product_sets(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_product_sets_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_product_sets._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_product_sets_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_import_product_sets") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_import_product_sets") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ImportProductSetsRequest.pb(product_search_service.ImportProductSetsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = product_search_service.ImportProductSetsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_product_sets(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_product_sets_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ImportProductSetsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.import_product_sets(request) + + +def test_import_product_sets_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.import_product_sets(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p3beta1/{parent=projects/*/locations/*}/productSets:import" % client.transport._host, args[1]) + + +def test_import_product_sets_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + +def test_import_product_sets_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProductSearchClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProductSearchGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + transports.ProductSearchRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "rest", +]) +def test_transport_kind(transport_name): + transport = ProductSearchClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ProductSearchGrpcTransport, + ) + +def test_product_search_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ProductSearchTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_product_search_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.vision_v1p3beta1.services.product_search.transports.ProductSearchTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ProductSearchTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_product_set', + 'list_product_sets', + 'get_product_set', + 'update_product_set', + 'delete_product_set', + 'create_product', + 'list_products', + 'get_product', + 'update_product', + 'delete_product', + 'create_reference_image', + 'delete_reference_image', + 'list_reference_images', + 'get_reference_image', + 'add_product_to_product_set', + 'remove_product_from_product_set', + 'list_products_in_product_set', + 'import_product_sets', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_product_search_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.vision_v1p3beta1.services.product_search.transports.ProductSearchTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductSearchTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id="octopus", + ) + + +def test_product_search_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.vision_v1p3beta1.services.product_search.transports.ProductSearchTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductSearchTransport() + adc.assert_called_once() + + +def test_product_search_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ProductSearchClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + ], +) +def test_product_search_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-vision',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + transports.ProductSearchRestTransport, + ], +) +def test_product_search_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ProductSearchGrpcTransport, grpc_helpers), + (transports.ProductSearchGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_product_search_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=["1", "2"], + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_product_search_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel") as mock_configure_mtls_channel: + transports.ProductSearchRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_product_search_rest_lro_client(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_search_host_no_port(transport_name): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_search_host_with_port(transport_name): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_product_search_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ProductSearchClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ProductSearchClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_product_set._session + session2 = client2.transport.create_product_set._session + assert session1 != session2 + session1 = client1.transport.list_product_sets._session + session2 = client2.transport.list_product_sets._session + assert session1 != session2 + session1 = client1.transport.get_product_set._session + session2 = client2.transport.get_product_set._session + assert session1 != session2 + session1 = client1.transport.update_product_set._session + session2 = client2.transport.update_product_set._session + assert session1 != session2 + session1 = client1.transport.delete_product_set._session + session2 = client2.transport.delete_product_set._session + assert session1 != session2 + session1 = client1.transport.create_product._session + session2 = client2.transport.create_product._session + assert session1 != session2 + session1 = client1.transport.list_products._session + session2 = client2.transport.list_products._session + assert session1 != session2 + session1 = client1.transport.get_product._session + session2 = client2.transport.get_product._session + assert session1 != session2 + session1 = client1.transport.update_product._session + session2 = client2.transport.update_product._session + assert session1 != session2 + session1 = client1.transport.delete_product._session + session2 = client2.transport.delete_product._session + assert session1 != session2 + session1 = client1.transport.create_reference_image._session + session2 = client2.transport.create_reference_image._session + assert session1 != session2 + session1 = client1.transport.delete_reference_image._session + session2 = client2.transport.delete_reference_image._session + assert session1 != session2 + session1 = client1.transport.list_reference_images._session + session2 = client2.transport.list_reference_images._session + assert session1 != session2 + session1 = client1.transport.get_reference_image._session + session2 = client2.transport.get_reference_image._session + assert session1 != session2 + session1 = client1.transport.add_product_to_product_set._session + session2 = client2.transport.add_product_to_product_set._session + assert session1 != session2 + session1 = client1.transport.remove_product_from_product_set._session + session2 = client2.transport.remove_product_from_product_set._session + assert session1 != session2 + session1 = client1.transport.list_products_in_product_set._session + session2 = client2.transport.list_products_in_product_set._session + assert session1 != session2 + session1 = client1.transport.import_product_sets._session + session2 = client2.transport.import_product_sets._session + assert session1 != session2 +def test_product_search_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductSearchGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_product_search_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductSearchGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_product_search_grpc_lro_client(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_search_grpc_lro_async_client(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_path(): + project = "squid" + location = "clam" + product = "whelk" + expected = "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + actual = ProductSearchClient.product_path(project, location, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "octopus", + "location": "oyster", + "product": "nudibranch", + } + path = ProductSearchClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_product_path(path) + assert expected == actual + +def test_product_set_path(): + project = "cuttlefish" + location = "mussel" + product_set = "winkle" + expected = "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + actual = ProductSearchClient.product_set_path(project, location, product_set) + assert expected == actual + + +def test_parse_product_set_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "product_set": "abalone", + } + path = ProductSearchClient.product_set_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_product_set_path(path) + assert expected == actual + +def test_reference_image_path(): + project = "squid" + location = "clam" + product = "whelk" + reference_image = "octopus" + expected = "projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}".format(project=project, location=location, product=product, reference_image=reference_image, ) + actual = ProductSearchClient.reference_image_path(project, location, product, reference_image) + assert expected == actual + + +def test_parse_reference_image_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "product": "cuttlefish", + "reference_image": "mussel", + } + path = ProductSearchClient.reference_image_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_reference_image_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "winkle" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ProductSearchClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nautilus", + } + path = ProductSearchClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "scallop" + expected = "folders/{folder}".format(folder=folder, ) + actual = ProductSearchClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "abalone", + } + path = ProductSearchClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "squid" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ProductSearchClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "clam", + } + path = ProductSearchClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "whelk" + expected = "projects/{project}".format(project=project, ) + actual = ProductSearchClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "octopus", + } + path = ProductSearchClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "oyster" + location = "nudibranch" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ProductSearchClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + } + path = ProductSearchClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ProductSearchTransport, '_prep_wrapped_messages') as prep: + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ProductSearchTransport, '_prep_wrapped_messages') as prep: + transport_class = ProductSearchClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/owl-bot-staging/v1p4beta1/.coveragerc b/owl-bot-staging/v1p4beta1/.coveragerc new file mode 100644 index 00000000..cbf0b85a --- /dev/null +++ b/owl-bot-staging/v1p4beta1/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/vision/__init__.py + google/cloud/vision/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/owl-bot-staging/v1p4beta1/.flake8 b/owl-bot-staging/v1p4beta1/.flake8 new file mode 100644 index 00000000..29227d4c --- /dev/null +++ b/owl-bot-staging/v1p4beta1/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2020 Google LLC +# +# Licensed 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 +# +# https://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. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/owl-bot-staging/v1p4beta1/MANIFEST.in b/owl-bot-staging/v1p4beta1/MANIFEST.in new file mode 100644 index 00000000..47dfa0c1 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/vision *.py +recursive-include google/cloud/vision_v1p4beta1 *.py diff --git a/owl-bot-staging/v1p4beta1/README.rst b/owl-bot-staging/v1p4beta1/README.rst new file mode 100644 index 00000000..39f9ca72 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Vision API +================================================= + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. Enable the Google Cloud Vision API. +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a `virtualenv`_ using pip. `virtualenv`_ is a tool to +create isolated Python environments. The basic problem it addresses is one of +dependencies and versions, and indirectly permissions. + +With `virtualenv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ + + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + /bin/pip install /path/to/library + + +Windows +^^^^^^^ + +.. code-block:: console + + python3 -m venv + \Scripts\activate + \Scripts\pip.exe install \path\to\library diff --git a/owl-bot-staging/v1p4beta1/docs/_static/custom.css b/owl-bot-staging/v1p4beta1/docs/_static/custom.css new file mode 100644 index 00000000..06423be0 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/v1p4beta1/docs/conf.py b/owl-bot-staging/v1p4beta1/docs/conf.py new file mode 100644 index 00000000..c75f569a --- /dev/null +++ b/owl-bot-staging/v1p4beta1/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# +# google-cloud-vision documentation build configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import shlex + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("..")) + +__version__ = "0.1.0" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = "4.0.1" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "sphinx.ext.coverage", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", +] + +# autodoc/autosummary flags +autoclass_content = "both" +autodoc_default_flags = ["members"] +autosummary_generate = True + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# Allow markdown includes (so releases.md can include CHANGLEOG.md) +# http://www.sphinx-doc.org/en/master/markdown.html +source_parsers = {".md": "recommonmark.parser.CommonMarkParser"} + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = u"google-cloud-vision" +copyright = u"2023, Google, LLC" +author = u"Google APIs" # TODO: autogenerate this bit + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = __version__ +# The short X.Y version. +version = ".".join(release.split(".")[0:2]) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "alabaster" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + "description": "Google Cloud Client Libraries for Python", + "github_user": "googleapis", + "github_repo": "google-cloud-python", + "github_banner": True, + "font_family": "'Roboto', Georgia, sans", + "head_font_family": "'Roboto', Georgia, serif", + "code_font_family": "'Roboto Mono', 'Consolas', monospace", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = "google-cloud-vision-doc" + +# -- Options for warnings ------------------------------------------------------ + + +suppress_warnings = [ + # Temporarily suppress this to avoid "more than one target found for + # cross-reference" warning, which are intractable for us to avoid while in + # a mono-repo. + # See https://github.com/sphinx-doc/sphinx/blob + # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 + "ref.python" +] + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', + # Latex figure (float) alignment + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + root_doc, + "google-cloud-vision.tex", + u"google-cloud-vision Documentation", + author, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + root_doc, + "google-cloud-vision", + u"Google Cloud Vision Documentation", + [author], + 1, + ) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + root_doc, + "google-cloud-vision", + u"google-cloud-vision Documentation", + author, + "google-cloud-vision", + "GAPIC library for Google Cloud Vision API", + "APIs", + ) +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("http://python.readthedocs.org/en/latest/", None), + "gax": ("https://gax-python.readthedocs.org/en/latest/", None), + "google-auth": ("https://google-auth.readthedocs.io/en/stable", None), + "google-gax": ("https://gax-python.readthedocs.io/en/latest/", None), + "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None), + "grpc": ("https://grpc.io/grpc/python/", None), + "requests": ("http://requests.kennethreitz.org/en/stable/", None), + "proto": ("https://proto-plus-python.readthedocs.io/en/stable", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), +} + + +# Napoleon settings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True diff --git a/owl-bot-staging/v1p4beta1/docs/index.rst b/owl-bot-staging/v1p4beta1/docs/index.rst new file mode 100644 index 00000000..ea7e0477 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + vision_v1p4beta1/services + vision_v1p4beta1/types diff --git a/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/image_annotator.rst b/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/image_annotator.rst new file mode 100644 index 00000000..28717262 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/image_annotator.rst @@ -0,0 +1,6 @@ +ImageAnnotator +-------------------------------- + +.. automodule:: google.cloud.vision_v1p4beta1.services.image_annotator + :members: + :inherited-members: diff --git a/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/product_search.rst b/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/product_search.rst new file mode 100644 index 00000000..895f0cba --- /dev/null +++ b/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/product_search.rst @@ -0,0 +1,10 @@ +ProductSearch +------------------------------- + +.. automodule:: google.cloud.vision_v1p4beta1.services.product_search + :members: + :inherited-members: + +.. automodule:: google.cloud.vision_v1p4beta1.services.product_search.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/services.rst b/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/services.rst new file mode 100644 index 00000000..2ebd0bbc --- /dev/null +++ b/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/services.rst @@ -0,0 +1,7 @@ +Services for Google Cloud Vision v1p4beta1 API +============================================== +.. toctree:: + :maxdepth: 2 + + image_annotator + product_search diff --git a/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/types.rst b/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/types.rst new file mode 100644 index 00000000..214f01b1 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/docs/vision_v1p4beta1/types.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Vision v1p4beta1 API +=========================================== + +.. automodule:: google.cloud.vision_v1p4beta1.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision/__init__.py b/owl-bot-staging/v1p4beta1/google/cloud/vision/__init__.py new file mode 100644 index 00000000..9b97a193 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision/__init__.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.vision_v1p4beta1.services.image_annotator.client import ImageAnnotatorClient +from google.cloud.vision_v1p4beta1.services.image_annotator.async_client import ImageAnnotatorAsyncClient +from google.cloud.vision_v1p4beta1.services.product_search.client import ProductSearchClient +from google.cloud.vision_v1p4beta1.services.product_search.async_client import ProductSearchAsyncClient + +from google.cloud.vision_v1p4beta1.types.face import Celebrity +from google.cloud.vision_v1p4beta1.types.face import FaceRecognitionParams +from google.cloud.vision_v1p4beta1.types.face import FaceRecognitionResult +from google.cloud.vision_v1p4beta1.types.geometry import BoundingPoly +from google.cloud.vision_v1p4beta1.types.geometry import NormalizedVertex +from google.cloud.vision_v1p4beta1.types.geometry import Position +from google.cloud.vision_v1p4beta1.types.geometry import Vertex +from google.cloud.vision_v1p4beta1.types.image_annotator import AnnotateFileRequest +from google.cloud.vision_v1p4beta1.types.image_annotator import AnnotateFileResponse +from google.cloud.vision_v1p4beta1.types.image_annotator import AnnotateImageRequest +from google.cloud.vision_v1p4beta1.types.image_annotator import AnnotateImageResponse +from google.cloud.vision_v1p4beta1.types.image_annotator import AsyncAnnotateFileRequest +from google.cloud.vision_v1p4beta1.types.image_annotator import AsyncAnnotateFileResponse +from google.cloud.vision_v1p4beta1.types.image_annotator import AsyncBatchAnnotateFilesRequest +from google.cloud.vision_v1p4beta1.types.image_annotator import AsyncBatchAnnotateFilesResponse +from google.cloud.vision_v1p4beta1.types.image_annotator import AsyncBatchAnnotateImagesRequest +from google.cloud.vision_v1p4beta1.types.image_annotator import AsyncBatchAnnotateImagesResponse +from google.cloud.vision_v1p4beta1.types.image_annotator import BatchAnnotateFilesRequest +from google.cloud.vision_v1p4beta1.types.image_annotator import BatchAnnotateFilesResponse +from google.cloud.vision_v1p4beta1.types.image_annotator import BatchAnnotateImagesRequest +from google.cloud.vision_v1p4beta1.types.image_annotator import BatchAnnotateImagesResponse +from google.cloud.vision_v1p4beta1.types.image_annotator import ColorInfo +from google.cloud.vision_v1p4beta1.types.image_annotator import CropHint +from google.cloud.vision_v1p4beta1.types.image_annotator import CropHintsAnnotation +from google.cloud.vision_v1p4beta1.types.image_annotator import CropHintsParams +from google.cloud.vision_v1p4beta1.types.image_annotator import DominantColorsAnnotation +from google.cloud.vision_v1p4beta1.types.image_annotator import EntityAnnotation +from google.cloud.vision_v1p4beta1.types.image_annotator import FaceAnnotation +from google.cloud.vision_v1p4beta1.types.image_annotator import Feature +from google.cloud.vision_v1p4beta1.types.image_annotator import GcsDestination +from google.cloud.vision_v1p4beta1.types.image_annotator import GcsSource +from google.cloud.vision_v1p4beta1.types.image_annotator import Image +from google.cloud.vision_v1p4beta1.types.image_annotator import ImageAnnotationContext +from google.cloud.vision_v1p4beta1.types.image_annotator import ImageContext +from google.cloud.vision_v1p4beta1.types.image_annotator import ImageProperties +from google.cloud.vision_v1p4beta1.types.image_annotator import ImageSource +from google.cloud.vision_v1p4beta1.types.image_annotator import InputConfig +from google.cloud.vision_v1p4beta1.types.image_annotator import LatLongRect +from google.cloud.vision_v1p4beta1.types.image_annotator import LocalizedObjectAnnotation +from google.cloud.vision_v1p4beta1.types.image_annotator import LocationInfo +from google.cloud.vision_v1p4beta1.types.image_annotator import OperationMetadata +from google.cloud.vision_v1p4beta1.types.image_annotator import OutputConfig +from google.cloud.vision_v1p4beta1.types.image_annotator import Property +from google.cloud.vision_v1p4beta1.types.image_annotator import SafeSearchAnnotation +from google.cloud.vision_v1p4beta1.types.image_annotator import TextDetectionParams +from google.cloud.vision_v1p4beta1.types.image_annotator import WebDetectionParams +from google.cloud.vision_v1p4beta1.types.image_annotator import Likelihood +from google.cloud.vision_v1p4beta1.types.product_search import ProductSearchParams +from google.cloud.vision_v1p4beta1.types.product_search import ProductSearchResults +from google.cloud.vision_v1p4beta1.types.product_search_service import AddProductToProductSetRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import BatchOperationMetadata +from google.cloud.vision_v1p4beta1.types.product_search_service import CreateProductRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import CreateProductSetRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import CreateReferenceImageRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import DeleteProductRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import DeleteProductSetRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import DeleteReferenceImageRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import GetProductRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import GetProductSetRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import GetReferenceImageRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import ImportProductSetsGcsSource +from google.cloud.vision_v1p4beta1.types.product_search_service import ImportProductSetsInputConfig +from google.cloud.vision_v1p4beta1.types.product_search_service import ImportProductSetsRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import ImportProductSetsResponse +from google.cloud.vision_v1p4beta1.types.product_search_service import ListProductSetsRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import ListProductSetsResponse +from google.cloud.vision_v1p4beta1.types.product_search_service import ListProductsInProductSetRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import ListProductsInProductSetResponse +from google.cloud.vision_v1p4beta1.types.product_search_service import ListProductsRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import ListProductsResponse +from google.cloud.vision_v1p4beta1.types.product_search_service import ListReferenceImagesRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import ListReferenceImagesResponse +from google.cloud.vision_v1p4beta1.types.product_search_service import Product +from google.cloud.vision_v1p4beta1.types.product_search_service import ProductSet +from google.cloud.vision_v1p4beta1.types.product_search_service import ProductSetPurgeConfig +from google.cloud.vision_v1p4beta1.types.product_search_service import PurgeProductsRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import ReferenceImage +from google.cloud.vision_v1p4beta1.types.product_search_service import RemoveProductFromProductSetRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import UpdateProductRequest +from google.cloud.vision_v1p4beta1.types.product_search_service import UpdateProductSetRequest +from google.cloud.vision_v1p4beta1.types.text_annotation import Block +from google.cloud.vision_v1p4beta1.types.text_annotation import Page +from google.cloud.vision_v1p4beta1.types.text_annotation import Paragraph +from google.cloud.vision_v1p4beta1.types.text_annotation import Symbol +from google.cloud.vision_v1p4beta1.types.text_annotation import TextAnnotation +from google.cloud.vision_v1p4beta1.types.text_annotation import Word +from google.cloud.vision_v1p4beta1.types.web_detection import WebDetection + +__all__ = ('ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', + 'ProductSearchClient', + 'ProductSearchAsyncClient', + 'Celebrity', + 'FaceRecognitionParams', + 'FaceRecognitionResult', + 'BoundingPoly', + 'NormalizedVertex', + 'Position', + 'Vertex', + 'AnnotateFileRequest', + 'AnnotateFileResponse', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'AsyncBatchAnnotateImagesRequest', + 'AsyncBatchAnnotateImagesResponse', + 'BatchAnnotateFilesRequest', + 'BatchAnnotateFilesResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'GcsDestination', + 'GcsSource', + 'Image', + 'ImageAnnotationContext', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'InputConfig', + 'LatLongRect', + 'LocalizedObjectAnnotation', + 'LocationInfo', + 'OperationMetadata', + 'OutputConfig', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'ProductSearchParams', + 'ProductSearchResults', + 'AddProductToProductSetRequest', + 'BatchOperationMetadata', + 'CreateProductRequest', + 'CreateProductSetRequest', + 'CreateReferenceImageRequest', + 'DeleteProductRequest', + 'DeleteProductSetRequest', + 'DeleteReferenceImageRequest', + 'GetProductRequest', + 'GetProductSetRequest', + 'GetReferenceImageRequest', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ListProductsRequest', + 'ListProductsResponse', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'Product', + 'ProductSet', + 'ProductSetPurgeConfig', + 'PurgeProductsRequest', + 'ReferenceImage', + 'RemoveProductFromProductSetRequest', + 'UpdateProductRequest', + 'UpdateProductSetRequest', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision/gapic_version.py b/owl-bot-staging/v1p4beta1/google/cloud/vision/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision/py.typed b/owl-bot-staging/v1p4beta1/google/cloud/vision/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/__init__.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/__init__.py new file mode 100644 index 00000000..58aae8d9 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/__init__.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.cloud.vision_v1p4beta1 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.image_annotator import ImageAnnotatorClient +from .services.image_annotator import ImageAnnotatorAsyncClient +from .services.product_search import ProductSearchClient +from .services.product_search import ProductSearchAsyncClient + +from .types.face import Celebrity +from .types.face import FaceRecognitionParams +from .types.face import FaceRecognitionResult +from .types.geometry import BoundingPoly +from .types.geometry import NormalizedVertex +from .types.geometry import Position +from .types.geometry import Vertex +from .types.image_annotator import AnnotateFileRequest +from .types.image_annotator import AnnotateFileResponse +from .types.image_annotator import AnnotateImageRequest +from .types.image_annotator import AnnotateImageResponse +from .types.image_annotator import AsyncAnnotateFileRequest +from .types.image_annotator import AsyncAnnotateFileResponse +from .types.image_annotator import AsyncBatchAnnotateFilesRequest +from .types.image_annotator import AsyncBatchAnnotateFilesResponse +from .types.image_annotator import AsyncBatchAnnotateImagesRequest +from .types.image_annotator import AsyncBatchAnnotateImagesResponse +from .types.image_annotator import BatchAnnotateFilesRequest +from .types.image_annotator import BatchAnnotateFilesResponse +from .types.image_annotator import BatchAnnotateImagesRequest +from .types.image_annotator import BatchAnnotateImagesResponse +from .types.image_annotator import ColorInfo +from .types.image_annotator import CropHint +from .types.image_annotator import CropHintsAnnotation +from .types.image_annotator import CropHintsParams +from .types.image_annotator import DominantColorsAnnotation +from .types.image_annotator import EntityAnnotation +from .types.image_annotator import FaceAnnotation +from .types.image_annotator import Feature +from .types.image_annotator import GcsDestination +from .types.image_annotator import GcsSource +from .types.image_annotator import Image +from .types.image_annotator import ImageAnnotationContext +from .types.image_annotator import ImageContext +from .types.image_annotator import ImageProperties +from .types.image_annotator import ImageSource +from .types.image_annotator import InputConfig +from .types.image_annotator import LatLongRect +from .types.image_annotator import LocalizedObjectAnnotation +from .types.image_annotator import LocationInfo +from .types.image_annotator import OperationMetadata +from .types.image_annotator import OutputConfig +from .types.image_annotator import Property +from .types.image_annotator import SafeSearchAnnotation +from .types.image_annotator import TextDetectionParams +from .types.image_annotator import WebDetectionParams +from .types.image_annotator import Likelihood +from .types.product_search import ProductSearchParams +from .types.product_search import ProductSearchResults +from .types.product_search_service import AddProductToProductSetRequest +from .types.product_search_service import BatchOperationMetadata +from .types.product_search_service import CreateProductRequest +from .types.product_search_service import CreateProductSetRequest +from .types.product_search_service import CreateReferenceImageRequest +from .types.product_search_service import DeleteProductRequest +from .types.product_search_service import DeleteProductSetRequest +from .types.product_search_service import DeleteReferenceImageRequest +from .types.product_search_service import GetProductRequest +from .types.product_search_service import GetProductSetRequest +from .types.product_search_service import GetReferenceImageRequest +from .types.product_search_service import ImportProductSetsGcsSource +from .types.product_search_service import ImportProductSetsInputConfig +from .types.product_search_service import ImportProductSetsRequest +from .types.product_search_service import ImportProductSetsResponse +from .types.product_search_service import ListProductSetsRequest +from .types.product_search_service import ListProductSetsResponse +from .types.product_search_service import ListProductsInProductSetRequest +from .types.product_search_service import ListProductsInProductSetResponse +from .types.product_search_service import ListProductsRequest +from .types.product_search_service import ListProductsResponse +from .types.product_search_service import ListReferenceImagesRequest +from .types.product_search_service import ListReferenceImagesResponse +from .types.product_search_service import Product +from .types.product_search_service import ProductSet +from .types.product_search_service import ProductSetPurgeConfig +from .types.product_search_service import PurgeProductsRequest +from .types.product_search_service import ReferenceImage +from .types.product_search_service import RemoveProductFromProductSetRequest +from .types.product_search_service import UpdateProductRequest +from .types.product_search_service import UpdateProductSetRequest +from .types.text_annotation import Block +from .types.text_annotation import Page +from .types.text_annotation import Paragraph +from .types.text_annotation import Symbol +from .types.text_annotation import TextAnnotation +from .types.text_annotation import Word +from .types.web_detection import WebDetection + +__all__ = ( + 'ImageAnnotatorAsyncClient', + 'ProductSearchAsyncClient', +'AddProductToProductSetRequest', +'AnnotateFileRequest', +'AnnotateFileResponse', +'AnnotateImageRequest', +'AnnotateImageResponse', +'AsyncAnnotateFileRequest', +'AsyncAnnotateFileResponse', +'AsyncBatchAnnotateFilesRequest', +'AsyncBatchAnnotateFilesResponse', +'AsyncBatchAnnotateImagesRequest', +'AsyncBatchAnnotateImagesResponse', +'BatchAnnotateFilesRequest', +'BatchAnnotateFilesResponse', +'BatchAnnotateImagesRequest', +'BatchAnnotateImagesResponse', +'BatchOperationMetadata', +'Block', +'BoundingPoly', +'Celebrity', +'ColorInfo', +'CreateProductRequest', +'CreateProductSetRequest', +'CreateReferenceImageRequest', +'CropHint', +'CropHintsAnnotation', +'CropHintsParams', +'DeleteProductRequest', +'DeleteProductSetRequest', +'DeleteReferenceImageRequest', +'DominantColorsAnnotation', +'EntityAnnotation', +'FaceAnnotation', +'FaceRecognitionParams', +'FaceRecognitionResult', +'Feature', +'GcsDestination', +'GcsSource', +'GetProductRequest', +'GetProductSetRequest', +'GetReferenceImageRequest', +'Image', +'ImageAnnotationContext', +'ImageAnnotatorClient', +'ImageContext', +'ImageProperties', +'ImageSource', +'ImportProductSetsGcsSource', +'ImportProductSetsInputConfig', +'ImportProductSetsRequest', +'ImportProductSetsResponse', +'InputConfig', +'LatLongRect', +'Likelihood', +'ListProductSetsRequest', +'ListProductSetsResponse', +'ListProductsInProductSetRequest', +'ListProductsInProductSetResponse', +'ListProductsRequest', +'ListProductsResponse', +'ListReferenceImagesRequest', +'ListReferenceImagesResponse', +'LocalizedObjectAnnotation', +'LocationInfo', +'NormalizedVertex', +'OperationMetadata', +'OutputConfig', +'Page', +'Paragraph', +'Position', +'Product', +'ProductSearchClient', +'ProductSearchParams', +'ProductSearchResults', +'ProductSet', +'ProductSetPurgeConfig', +'Property', +'PurgeProductsRequest', +'ReferenceImage', +'RemoveProductFromProductSetRequest', +'SafeSearchAnnotation', +'Symbol', +'TextAnnotation', +'TextDetectionParams', +'UpdateProductRequest', +'UpdateProductSetRequest', +'Vertex', +'WebDetection', +'WebDetectionParams', +'Word', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/gapic_metadata.json b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/gapic_metadata.json new file mode 100644 index 00000000..9e0f3410 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/gapic_metadata.json @@ -0,0 +1,392 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.vision_v1p4beta1", + "protoPackage": "google.cloud.vision.v1p4beta1", + "schema": "1.0", + "services": { + "ImageAnnotator": { + "clients": { + "grpc": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "AsyncBatchAnnotateImages": { + "methods": [ + "async_batch_annotate_images" + ] + }, + "BatchAnnotateFiles": { + "methods": [ + "batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ImageAnnotatorAsyncClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "AsyncBatchAnnotateImages": { + "methods": [ + "async_batch_annotate_images" + ] + }, + "BatchAnnotateFiles": { + "methods": [ + "batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + }, + "rest": { + "libraryClient": "ImageAnnotatorClient", + "rpcs": { + "AsyncBatchAnnotateFiles": { + "methods": [ + "async_batch_annotate_files" + ] + }, + "AsyncBatchAnnotateImages": { + "methods": [ + "async_batch_annotate_images" + ] + }, + "BatchAnnotateFiles": { + "methods": [ + "batch_annotate_files" + ] + }, + "BatchAnnotateImages": { + "methods": [ + "batch_annotate_images" + ] + } + } + } + } + }, + "ProductSearch": { + "clients": { + "grpc": { + "libraryClient": "ProductSearchClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ProductSearchAsyncClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + }, + "rest": { + "libraryClient": "ProductSearchClient", + "rpcs": { + "AddProductToProductSet": { + "methods": [ + "add_product_to_product_set" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "CreateProductSet": { + "methods": [ + "create_product_set" + ] + }, + "CreateReferenceImage": { + "methods": [ + "create_reference_image" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "DeleteProductSet": { + "methods": [ + "delete_product_set" + ] + }, + "DeleteReferenceImage": { + "methods": [ + "delete_reference_image" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "GetProductSet": { + "methods": [ + "get_product_set" + ] + }, + "GetReferenceImage": { + "methods": [ + "get_reference_image" + ] + }, + "ImportProductSets": { + "methods": [ + "import_product_sets" + ] + }, + "ListProductSets": { + "methods": [ + "list_product_sets" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "ListProductsInProductSet": { + "methods": [ + "list_products_in_product_set" + ] + }, + "ListReferenceImages": { + "methods": [ + "list_reference_images" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveProductFromProductSet": { + "methods": [ + "remove_product_from_product_set" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + }, + "UpdateProductSet": { + "methods": [ + "update_product_set" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/gapic_version.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +__version__ = "0.0.0" # {x-release-please-version} diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/py.typed b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/py.typed new file mode 100644 index 00000000..8cb07491 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-vision package uses inline types. diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/__init__.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/__init__.py new file mode 100644 index 00000000..89a37dc9 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/__init__.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/__init__.py new file mode 100644 index 00000000..ee708f26 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .client import ImageAnnotatorClient +from .async_client import ImageAnnotatorAsyncClient + +__all__ = ( + 'ImageAnnotatorClient', + 'ImageAnnotatorAsyncClient', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/async_client.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/async_client.py new file mode 100644 index 00000000..4bd1f954 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/async_client.py @@ -0,0 +1,660 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.vision_v1p4beta1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p4beta1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .client import ImageAnnotatorClient + + +class ImageAnnotatorAsyncClient: + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + _client: ImageAnnotatorClient + + DEFAULT_ENDPOINT = ImageAnnotatorClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ImageAnnotatorClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(ImageAnnotatorClient.product_path) + parse_product_path = staticmethod(ImageAnnotatorClient.parse_product_path) + product_set_path = staticmethod(ImageAnnotatorClient.product_set_path) + parse_product_set_path = staticmethod(ImageAnnotatorClient.parse_product_set_path) + common_billing_account_path = staticmethod(ImageAnnotatorClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ImageAnnotatorClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ImageAnnotatorClient.common_folder_path) + parse_common_folder_path = staticmethod(ImageAnnotatorClient.parse_common_folder_path) + common_organization_path = staticmethod(ImageAnnotatorClient.common_organization_path) + parse_common_organization_path = staticmethod(ImageAnnotatorClient.parse_common_organization_path) + common_project_path = staticmethod(ImageAnnotatorClient.common_project_path) + parse_common_project_path = staticmethod(ImageAnnotatorClient.parse_common_project_path) + common_location_path = staticmethod(ImageAnnotatorClient.common_location_path) + parse_common_location_path = staticmethod(ImageAnnotatorClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_info.__func__(ImageAnnotatorAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorAsyncClient: The constructed client. + """ + return ImageAnnotatorClient.from_service_account_file.__func__(ImageAnnotatorAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ImageAnnotatorClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ImageAnnotatorClient).get_transport_class, type(ImageAnnotatorClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ImageAnnotatorTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ImageAnnotatorClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_batch_annotate_images(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.BatchAnnotateImagesRequest, dict]]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (:class:`MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]`): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.BatchAnnotateImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def batch_annotate_files(self, + request: Optional[Union[image_annotator.BatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateFilesResponse: + r"""Service that performs image detection and annotation + for a batch of files. Now only "application/pdf", + "image/tiff" and "image/gif" are supported. + + This service will extract at most 5 (customers can + specify which 5 in AnnotateFileRequest.pages) frames + (gif) or pages (pdf or tiff) from each file provided and + perform detection and annotation for each image + extracted. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_batch_annotate_files(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.BatchAnnotateFilesRequest( + ) + + # Make the request + response = await client.batch_annotate_files(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.BatchAnnotateFilesRequest, dict]]): + The request object. A list of requests to annotate files + using the BatchAnnotateFiles API. + requests (:class:`MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateFileRequest]`): + Required. The list of file annotation + requests. Right now we support only one + AnnotateFileRequest in + BatchAnnotateFilesRequest. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.BatchAnnotateFilesResponse: + A list of file annotation responses. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.BatchAnnotateFilesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def async_batch_annotate_images(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + output_config: Optional[image_annotator.OutputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Run asynchronous image detection and annotation for a list of + images. + + Progress and results can be retrieved through the + ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateImagesResponse`` (results). + + This service will write image annotation outputs to json files + in customer GCS bucket, each json file containing + BatchAnnotateImagesResponse proto. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_async_batch_annotate_images(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AsyncBatchAnnotateImagesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_images(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateImagesRequest, dict]]): + The request object. Request for async image annotation + for a list of images. + requests (:class:`MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]`): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + output_config (:class:`google.cloud.vision_v1p4beta1.types.OutputConfig`): + Required. The desired output location + and metadata (e.g. format). + + This corresponds to the ``output_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateImagesResponse` + Response to an async batch image annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests, output_config]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.AsyncBatchAnnotateImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if output_config is not None: + request.output_config = output_config + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.async_batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + image_annotator.AsyncBatchAnnotateImagesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + async def async_batch_annotate_files(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AsyncAnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateFilesRequest, dict]]): + The request object. Multiple async file annotation + requests are batched into a single + service call. + requests (:class:`MutableSequence[google.cloud.vision_v1p4beta1.types.AsyncAnnotateFileRequest]`): + Required. Individual async file + annotation requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateFilesResponse` + Response to an async batch file annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = image_annotator.AsyncBatchAnnotateFilesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests: + request.requests.extend(requests) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.async_batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + image_annotator.AsyncBatchAnnotateFilesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ImageAnnotatorAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorAsyncClient", +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/client.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/client.py new file mode 100644 index 00000000..66f3280e --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/client.py @@ -0,0 +1,853 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import os +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast + +from google.cloud.vision_v1p4beta1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p4beta1.types import image_annotator +from .transports.base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ImageAnnotatorGrpcTransport +from .transports.grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .transports.rest import ImageAnnotatorRestTransport + + +class ImageAnnotatorClientMeta(type): + """Metaclass for the ImageAnnotator client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] + _transport_registry["grpc"] = ImageAnnotatorGrpcTransport + _transport_registry["grpc_asyncio"] = ImageAnnotatorGrpcAsyncIOTransport + _transport_registry["rest"] = ImageAnnotatorRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ImageAnnotatorTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ImageAnnotatorClient(metaclass=ImageAnnotatorClientMeta): + """Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "vision.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ImageAnnotatorClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ImageAnnotatorTransport: + """Returns the transport used by the client instance. + + Returns: + ImageAnnotatorTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_set_path(project: str,location: str,product_set: str,) -> str: + """Returns a fully-qualified product_set string.""" + return "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + + @staticmethod + def parse_product_set_path(path: str) -> Dict[str,str]: + """Parses a product_set path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/productSets/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ImageAnnotatorTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the image annotator client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ImageAnnotatorTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ImageAnnotatorTransport): + # transport is a ImageAnnotatorTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def batch_annotate_images(self, + request: Optional[Union[image_annotator.BatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Run image detection and annotation for a batch of + images. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_batch_annotate_images(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.BatchAnnotateImagesRequest, dict]): + The request object. Multiple image annotation requests + are batched into a single service call. + requests (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.BatchAnnotateImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.BatchAnnotateImagesRequest): + request = image_annotator.BatchAnnotateImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_annotate_images] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_annotate_files(self, + request: Optional[Union[image_annotator.BatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> image_annotator.BatchAnnotateFilesResponse: + r"""Service that performs image detection and annotation + for a batch of files. Now only "application/pdf", + "image/tiff" and "image/gif" are supported. + + This service will extract at most 5 (customers can + specify which 5 in AnnotateFileRequest.pages) frames + (gif) or pages (pdf or tiff) from each file provided and + perform detection and annotation for each image + extracted. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_batch_annotate_files(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.BatchAnnotateFilesRequest( + ) + + # Make the request + response = client.batch_annotate_files(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.BatchAnnotateFilesRequest, dict]): + The request object. A list of requests to annotate files + using the BatchAnnotateFiles API. + requests (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateFileRequest]): + Required. The list of file annotation + requests. Right now we support only one + AnnotateFileRequest in + BatchAnnotateFilesRequest. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.BatchAnnotateFilesResponse: + A list of file annotation responses. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.BatchAnnotateFilesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.BatchAnnotateFilesRequest): + request = image_annotator.BatchAnnotateFilesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_annotate_files] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def async_batch_annotate_images(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateImagesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AnnotateImageRequest]] = None, + output_config: Optional[image_annotator.OutputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Run asynchronous image detection and annotation for a list of + images. + + Progress and results can be retrieved through the + ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateImagesResponse`` (results). + + This service will write image annotation outputs to json files + in customer GCS bucket, each json file containing + BatchAnnotateImagesResponse proto. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_async_batch_annotate_images(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AsyncBatchAnnotateImagesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_images(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateImagesRequest, dict]): + The request object. Request for async image annotation + for a list of images. + requests (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + output_config (google.cloud.vision_v1p4beta1.types.OutputConfig): + Required. The desired output location + and metadata (e.g. format). + + This corresponds to the ``output_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateImagesResponse` + Response to an async batch image annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests, output_config]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.AsyncBatchAnnotateImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.AsyncBatchAnnotateImagesRequest): + request = image_annotator.AsyncBatchAnnotateImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + if output_config is not None: + request.output_config = output_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.async_batch_annotate_images] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + image_annotator.AsyncBatchAnnotateImagesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + def async_batch_annotate_files(self, + request: Optional[Union[image_annotator.AsyncBatchAnnotateFilesRequest, dict]] = None, + *, + requests: Optional[MutableSequence[image_annotator.AsyncAnnotateFileRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateFilesRequest, dict]): + The request object. Multiple async file annotation + requests are batched into a single + service call. + requests (MutableSequence[google.cloud.vision_v1p4beta1.types.AsyncAnnotateFileRequest]): + Required. Individual async file + annotation requests for this batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateFilesResponse` + Response to an async batch file annotation request. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([requests]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a image_annotator.AsyncBatchAnnotateFilesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, image_annotator.AsyncBatchAnnotateFilesRequest): + request = image_annotator.AsyncBatchAnnotateFilesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.async_batch_annotate_files] + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + image_annotator.AsyncBatchAnnotateFilesResponse, + metadata_type=image_annotator.OperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ImageAnnotatorClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ImageAnnotatorClient", +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/__init__.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/__init__.py new file mode 100644 index 00000000..ad6cf948 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +from typing import Dict, Type + +from .base import ImageAnnotatorTransport +from .grpc import ImageAnnotatorGrpcTransport +from .grpc_asyncio import ImageAnnotatorGrpcAsyncIOTransport +from .rest import ImageAnnotatorRestTransport +from .rest import ImageAnnotatorRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ImageAnnotatorTransport]] +_transport_registry['grpc'] = ImageAnnotatorGrpcTransport +_transport_registry['grpc_asyncio'] = ImageAnnotatorGrpcAsyncIOTransport +_transport_registry['rest'] = ImageAnnotatorRestTransport + +__all__ = ( + 'ImageAnnotatorTransport', + 'ImageAnnotatorGrpcTransport', + 'ImageAnnotatorGrpcAsyncIOTransport', + 'ImageAnnotatorRestTransport', + 'ImageAnnotatorRestInterceptor', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/base.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/base.py new file mode 100644 index 00000000..a9638186 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/base.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.vision_v1p4beta1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.vision_v1p4beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ImageAnnotatorTransport(abc.ABC): + """Abstract transport class for ImageAnnotator.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', + ) + + DEFAULT_HOST: str = 'vision.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience(api_audience if api_audience else host) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.batch_annotate_images: gapic_v1.method.wrap_method( + self.batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.batch_annotate_files: gapic_v1.method.wrap_method( + self.batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.async_batch_annotate_images: gapic_v1.method.wrap_method( + self.async_batch_annotate_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.async_batch_annotate_files: gapic_v1.method.wrap_method( + self.async_batch_annotate_files, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Union[ + image_annotator.BatchAnnotateImagesResponse, + Awaitable[image_annotator.BatchAnnotateImagesResponse] + ]]: + raise NotImplementedError() + + @property + def batch_annotate_files(self) -> Callable[ + [image_annotator.BatchAnnotateFilesRequest], + Union[ + image_annotator.BatchAnnotateFilesResponse, + Awaitable[image_annotator.BatchAnnotateFilesResponse] + ]]: + raise NotImplementedError() + + @property + def async_batch_annotate_images(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateImagesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ImageAnnotatorTransport', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/grpc.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/grpc.py new file mode 100644 index 00000000..fcc5c754 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.vision_v1p4beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO + + +class ImageAnnotatorGrpcTransport(ImageAnnotatorTransport): + """gRPC backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + ~.BatchAnnotateImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + @property + def batch_annotate_files(self) -> Callable[ + [image_annotator.BatchAnnotateFilesRequest], + image_annotator.BatchAnnotateFilesResponse]: + r"""Return a callable for the batch annotate files method over gRPC. + + Service that performs image detection and annotation + for a batch of files. Now only "application/pdf", + "image/tiff" and "image/gif" are supported. + + This service will extract at most 5 (customers can + specify which 5 in AnnotateFileRequest.pages) frames + (gif) or pages (pdf or tiff) from each file provided and + perform detection and annotation for each image + extracted. + + Returns: + Callable[[~.BatchAnnotateFilesRequest], + ~.BatchAnnotateFilesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_files' not in self._stubs: + self._stubs['batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ImageAnnotator/BatchAnnotateFiles', + request_serializer=image_annotator.BatchAnnotateFilesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateFilesResponse.deserialize, + ) + return self._stubs['batch_annotate_files'] + + @property + def async_batch_annotate_images(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateImagesRequest], + operations_pb2.Operation]: + r"""Return a callable for the async batch annotate images method over gRPC. + + Run asynchronous image detection and annotation for a list of + images. + + Progress and results can be retrieved through the + ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateImagesResponse`` (results). + + This service will write image annotation outputs to json files + in customer GCS bucket, each json file containing + BatchAnnotateImagesResponse proto. + + Returns: + Callable[[~.AsyncBatchAnnotateImagesRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_images' not in self._stubs: + self._stubs['async_batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ImageAnnotator/AsyncBatchAnnotateImages', + request_serializer=image_annotator.AsyncBatchAnnotateImagesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_images'] + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + operations_pb2.Operation]: + r"""Return a callable for the async batch annotate files method over gRPC. + + Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + Returns: + Callable[[~.AsyncBatchAnnotateFilesRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_files' not in self._stubs: + self._stubs['async_batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ImageAnnotator/AsyncBatchAnnotateFiles', + request_serializer=image_annotator.AsyncBatchAnnotateFilesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_files'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ImageAnnotatorGrpcTransport', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/grpc_asyncio.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/grpc_asyncio.py new file mode 100644 index 00000000..2c71c286 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/grpc_asyncio.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.vision_v1p4beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO +from .grpc import ImageAnnotatorGrpcTransport + + +class ImageAnnotatorGrpcAsyncIOTransport(ImageAnnotatorTransport): + """gRPC AsyncIO backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + Awaitable[image_annotator.BatchAnnotateImagesResponse]]: + r"""Return a callable for the batch annotate images method over gRPC. + + Run image detection and annotation for a batch of + images. + + Returns: + Callable[[~.BatchAnnotateImagesRequest], + Awaitable[~.BatchAnnotateImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_images' not in self._stubs: + self._stubs['batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ImageAnnotator/BatchAnnotateImages', + request_serializer=image_annotator.BatchAnnotateImagesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateImagesResponse.deserialize, + ) + return self._stubs['batch_annotate_images'] + + @property + def batch_annotate_files(self) -> Callable[ + [image_annotator.BatchAnnotateFilesRequest], + Awaitable[image_annotator.BatchAnnotateFilesResponse]]: + r"""Return a callable for the batch annotate files method over gRPC. + + Service that performs image detection and annotation + for a batch of files. Now only "application/pdf", + "image/tiff" and "image/gif" are supported. + + This service will extract at most 5 (customers can + specify which 5 in AnnotateFileRequest.pages) frames + (gif) or pages (pdf or tiff) from each file provided and + perform detection and annotation for each image + extracted. + + Returns: + Callable[[~.BatchAnnotateFilesRequest], + Awaitable[~.BatchAnnotateFilesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'batch_annotate_files' not in self._stubs: + self._stubs['batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ImageAnnotator/BatchAnnotateFiles', + request_serializer=image_annotator.BatchAnnotateFilesRequest.serialize, + response_deserializer=image_annotator.BatchAnnotateFilesResponse.deserialize, + ) + return self._stubs['batch_annotate_files'] + + @property + def async_batch_annotate_images(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateImagesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the async batch annotate images method over gRPC. + + Run asynchronous image detection and annotation for a list of + images. + + Progress and results can be retrieved through the + ``google.longrunning.Operations`` interface. + ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateImagesResponse`` (results). + + This service will write image annotation outputs to json files + in customer GCS bucket, each json file containing + BatchAnnotateImagesResponse proto. + + Returns: + Callable[[~.AsyncBatchAnnotateImagesRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_images' not in self._stubs: + self._stubs['async_batch_annotate_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ImageAnnotator/AsyncBatchAnnotateImages', + request_serializer=image_annotator.AsyncBatchAnnotateImagesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_images'] + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the async batch annotate files method over gRPC. + + Run asynchronous image detection and annotation for a list of + generic files, such as PDF files, which may contain multiple + pages and multiple images per page. Progress and results can be + retrieved through the ``google.longrunning.Operations`` + interface. ``Operation.metadata`` contains ``OperationMetadata`` + (metadata). ``Operation.response`` contains + ``AsyncBatchAnnotateFilesResponse`` (results). + + Returns: + Callable[[~.AsyncBatchAnnotateFilesRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'async_batch_annotate_files' not in self._stubs: + self._stubs['async_batch_annotate_files'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ImageAnnotator/AsyncBatchAnnotateFiles', + request_serializer=image_annotator.AsyncBatchAnnotateFilesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['async_batch_annotate_files'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ImageAnnotatorGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/rest.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/rest.py new file mode 100644 index 00000000..349deb3f --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/image_annotator/transports/rest.py @@ -0,0 +1,696 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.auth.transport.requests import AuthorizedSession # type: ignore +import json # type: ignore +import grpc # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.api_core import rest_helpers +from google.api_core import rest_streaming +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from google.api_core import operations_v1 +from requests import __version__ as requests_version +import dataclasses +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.cloud.vision_v1p4beta1.types import image_annotator +from google.longrunning import operations_pb2 # type: ignore + +from .base import ImageAnnotatorTransport, DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ImageAnnotatorRestInterceptor: + """Interceptor for ImageAnnotator. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ImageAnnotatorRestTransport. + + .. code-block:: python + class MyCustomImageAnnotatorInterceptor(ImageAnnotatorRestInterceptor): + def pre_async_batch_annotate_files(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_async_batch_annotate_files(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_async_batch_annotate_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_async_batch_annotate_images(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_annotate_files(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_annotate_files(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_annotate_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_annotate_images(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ImageAnnotatorRestTransport(interceptor=MyCustomImageAnnotatorInterceptor()) + client = ImageAnnotatorClient(transport=transport) + + + """ + def pre_async_batch_annotate_files(self, request: image_annotator.AsyncBatchAnnotateFilesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.AsyncBatchAnnotateFilesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for async_batch_annotate_files + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_async_batch_annotate_files(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for async_batch_annotate_files + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + def pre_async_batch_annotate_images(self, request: image_annotator.AsyncBatchAnnotateImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.AsyncBatchAnnotateImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for async_batch_annotate_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_async_batch_annotate_images(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for async_batch_annotate_images + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + def pre_batch_annotate_files(self, request: image_annotator.BatchAnnotateFilesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.BatchAnnotateFilesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_annotate_files + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_batch_annotate_files(self, response: image_annotator.BatchAnnotateFilesResponse) -> image_annotator.BatchAnnotateFilesResponse: + """Post-rpc interceptor for batch_annotate_files + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + def pre_batch_annotate_images(self, request: image_annotator.BatchAnnotateImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[image_annotator.BatchAnnotateImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ImageAnnotator server. + """ + return request, metadata + + def post_batch_annotate_images(self, response: image_annotator.BatchAnnotateImagesResponse) -> image_annotator.BatchAnnotateImagesResponse: + """Post-rpc interceptor for batch_annotate_images + + Override in a subclass to manipulate the response + after it is returned by the ImageAnnotator server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ImageAnnotatorRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ImageAnnotatorRestInterceptor + + +class ImageAnnotatorRestTransport(ImageAnnotatorTransport): + """REST backend transport for ImageAnnotator. + + Service that performs Google Cloud Vision API detection tasks + over client images, such as face, landmark, logo, label, and + text detection. The ImageAnnotator service returns detected + entities from the images. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[ + ], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + interceptor: Optional[ImageAnnotatorRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError(f"Unexpected hostname structure: {host}") # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ImageAnnotatorRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1p4beta1") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AsyncBatchAnnotateFiles(ImageAnnotatorRestStub): + def __hash__(self): + return hash("AsyncBatchAnnotateFiles") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.AsyncBatchAnnotateFilesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the async batch annotate + files method over HTTP. + + Args: + request (~.image_annotator.AsyncBatchAnnotateFilesRequest): + The request object. Multiple async file annotation + requests are batched into a single + service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/files:asyncBatchAnnotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_async_batch_annotate_files(request, metadata) + pb_request = image_annotator.AsyncBatchAnnotateFilesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_async_batch_annotate_files(resp) + return resp + + class _AsyncBatchAnnotateImages(ImageAnnotatorRestStub): + def __hash__(self): + return hash("AsyncBatchAnnotateImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.AsyncBatchAnnotateImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the async batch annotate + images method over HTTP. + + Args: + request (~.image_annotator.AsyncBatchAnnotateImagesRequest): + The request object. Request for async image annotation + for a list of images. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/images:asyncBatchAnnotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_async_batch_annotate_images(request, metadata) + pb_request = image_annotator.AsyncBatchAnnotateImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_async_batch_annotate_images(resp) + return resp + + class _BatchAnnotateFiles(ImageAnnotatorRestStub): + def __hash__(self): + return hash("BatchAnnotateFiles") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.BatchAnnotateFilesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> image_annotator.BatchAnnotateFilesResponse: + r"""Call the batch annotate files method over HTTP. + + Args: + request (~.image_annotator.BatchAnnotateFilesRequest): + The request object. A list of requests to annotate files + using the BatchAnnotateFiles API. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.image_annotator.BatchAnnotateFilesResponse: + A list of file annotation responses. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/files:annotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_annotate_files(request, metadata) + pb_request = image_annotator.BatchAnnotateFilesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = image_annotator.BatchAnnotateFilesResponse() + pb_resp = image_annotator.BatchAnnotateFilesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_annotate_files(resp) + return resp + + class _BatchAnnotateImages(ImageAnnotatorRestStub): + def __hash__(self): + return hash("BatchAnnotateImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: image_annotator.BatchAnnotateImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> image_annotator.BatchAnnotateImagesResponse: + r"""Call the batch annotate images method over HTTP. + + Args: + request (~.image_annotator.BatchAnnotateImagesRequest): + The request object. Multiple image annotation requests + are batched into a single service call. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.image_annotator.BatchAnnotateImagesResponse: + Response to a batch image annotation + request. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/images:annotate', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_annotate_images(request, metadata) + pb_request = image_annotator.BatchAnnotateImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = image_annotator.BatchAnnotateImagesResponse() + pb_resp = image_annotator.BatchAnnotateImagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_annotate_images(resp) + return resp + + @property + def async_batch_annotate_files(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateFilesRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AsyncBatchAnnotateFiles(self._session, self._host, self._interceptor) # type: ignore + + @property + def async_batch_annotate_images(self) -> Callable[ + [image_annotator.AsyncBatchAnnotateImagesRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AsyncBatchAnnotateImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_annotate_files(self) -> Callable[ + [image_annotator.BatchAnnotateFilesRequest], + image_annotator.BatchAnnotateFilesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchAnnotateFiles(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_annotate_images(self) -> Callable[ + [image_annotator.BatchAnnotateImagesRequest], + image_annotator.BatchAnnotateImagesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchAnnotateImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ImageAnnotatorRestTransport', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/__init__.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/__init__.py new file mode 100644 index 00000000..f48c4b91 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .client import ProductSearchClient +from .async_client import ProductSearchAsyncClient + +__all__ = ( + 'ProductSearchClient', + 'ProductSearchAsyncClient', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/async_client.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/async_client.py new file mode 100644 index 00000000..6cb48197 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/async_client.py @@ -0,0 +1,2606 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.vision_v1p4beta1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p4beta1.services.product_search import pagers +from google.cloud.vision_v1p4beta1.types import geometry +from google.cloud.vision_v1p4beta1.types import product_search_service +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .client import ProductSearchClient + + +class ProductSearchAsyncClient: + """Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p4beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p4beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p4beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p4beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + """ + + _client: ProductSearchClient + + DEFAULT_ENDPOINT = ProductSearchClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ProductSearchClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(ProductSearchClient.product_path) + parse_product_path = staticmethod(ProductSearchClient.parse_product_path) + product_set_path = staticmethod(ProductSearchClient.product_set_path) + parse_product_set_path = staticmethod(ProductSearchClient.parse_product_set_path) + reference_image_path = staticmethod(ProductSearchClient.reference_image_path) + parse_reference_image_path = staticmethod(ProductSearchClient.parse_reference_image_path) + common_billing_account_path = staticmethod(ProductSearchClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ProductSearchClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ProductSearchClient.common_folder_path) + parse_common_folder_path = staticmethod(ProductSearchClient.parse_common_folder_path) + common_organization_path = staticmethod(ProductSearchClient.common_organization_path) + parse_common_organization_path = staticmethod(ProductSearchClient.parse_common_organization_path) + common_project_path = staticmethod(ProductSearchClient.common_project_path) + parse_common_project_path = staticmethod(ProductSearchClient.parse_common_project_path) + common_location_path = staticmethod(ProductSearchClient.common_location_path) + parse_common_location_path = staticmethod(ProductSearchClient.parse_common_location_path) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchAsyncClient: The constructed client. + """ + return ProductSearchClient.from_service_account_info.__func__(ProductSearchAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchAsyncClient: The constructed client. + """ + return ProductSearchClient.from_service_account_file.__func__(ProductSearchAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ProductSearchClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductSearchTransport: + """Returns the transport used by the client instance. + + Returns: + ProductSearchTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ProductSearchClient).get_transport_class, type(ProductSearchClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ProductSearchTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product search client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.ProductSearchTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ProductSearchClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_product_set(self, + request: Optional[Union[product_search_service.CreateProductSetRequest, dict]] = None, + *, + parent: Optional[str] = None, + product_set: Optional[product_search_service.ProductSet] = None, + product_set_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_create_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.CreateProductSetRequest, dict]]): + The request object. Request message for the ``CreateProductSet`` method. + parent (:class:`str`): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set (:class:`google.cloud.vision_v1p4beta1.types.ProductSet`): + Required. The ProductSet to create. + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set_id (:class:`str`): + A user-supplied resource id for this ProductSet. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_set_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product_set, product_set_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product_set is not None: + request.product_set = product_set + if product_set_id is not None: + request.product_set_id = product_set_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_product_sets(self, + request: Optional[Union[product_search_service.ListProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductSetsAsyncPager: + r"""Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_list_product_sets(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.ListProductSetsRequest, dict]]): + The request object. Request message for the ``ListProductSets`` method. + parent (:class:`str`): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductSetsAsyncPager: + Response message for the ListProductSets method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductSetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductSetsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_product_set(self, + request: Optional[Union[product_search_service.GetProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_get_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.GetProductSetRequest, dict]]): + The request object. Request message for the ``GetProductSet`` method. + name (:class:`str`): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_product_set(self, + request: Optional[Union[product_search_service.UpdateProductSetRequest, dict]] = None, + *, + product_set: Optional[product_search_service.ProductSet] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_update_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.UpdateProductSetRequest( + ) + + # Make the request + response = await client.update_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.UpdateProductSetRequest, dict]]): + The request object. Request message for the ``UpdateProductSet`` method. + product_set (:class:`google.cloud.vision_v1p4beta1.types.ProductSet`): + Required. The ProductSet resource + which replaces the one on the server. + + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask path is ``display_name``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product_set, update_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.UpdateProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product_set is not None: + request.product_set = product_set + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product_set.name", request.product_set.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_product_set(self, + request: Optional[Union[product_search_service.DeleteProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a ProductSet. Products and + ReferenceImages in the ProductSet are not deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_delete_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + await client.delete_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.DeleteProductSetRequest, dict]]): + The request object. Request message for the ``DeleteProductSet`` method. + name (:class:`str`): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def create_product(self, + request: Optional[Union[product_search_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[product_search_service.Product] = None, + product_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_create_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.CreateProductRequest, dict]]): + The request object. Request message for the ``CreateProduct`` method. + parent (:class:`str`): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`google.cloud.vision_v1p4beta1.types.Product`): + Required. The product to create. + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_id (:class:`str`): + A user-supplied resource id for this Product. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product, product_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product is not None: + request.product = product + if product_id is not None: + request.product_id = product_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_products(self, + request: Optional[Union[product_search_service.ListProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsAsyncPager: + r"""Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_list_products(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.ListProductsRequest, dict]]): + The request object. Request message for the ``ListProducts`` method. + parent (:class:`str`): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductsAsyncPager: + Response message for the ListProducts method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_products, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_product(self, + request: Optional[Union[product_search_service.GetProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_get_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.GetProductRequest, dict]]): + The request object. Request message for the ``GetProduct`` method. + name (:class:`str`): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_product(self, + request: Optional[Union[product_search_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[product_search_service.Product] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Makes changes to a Product resource. Only the ``display_name``, + ``description``, and ``labels`` fields can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_update_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.UpdateProductRequest( + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.UpdateProductRequest, dict]]): + The request object. Request message for the ``UpdateProduct`` method. + product (:class:`google.cloud.vision_v1p4beta1.types.Product`): + Required. The Product resource which + replaces the one on the server. + product.name is immutable. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask paths include ``product_labels``, ``display_name``, + and ``description``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product, update_mask]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.UpdateProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product.name", request.product.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_product(self, + request: Optional[Union[product_search_service.DeleteProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a product and its reference + images. + Metadata of the product and all its images will be + deleted right away, but search queries against + ProductSets containing the product may still work until + all related caches are refreshed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_delete_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.DeleteProductRequest, dict]]): + The request object. Request message for the ``DeleteProduct`` method. + name (:class:`str`): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteProductRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def create_reference_image(self, + request: Optional[Union[product_search_service.CreateReferenceImageRequest, dict]] = None, + *, + parent: Optional[str] = None, + reference_image: Optional[product_search_service.ReferenceImage] = None, + reference_image_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_create_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + reference_image = vision_v1p4beta1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1p4beta1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = await client.create_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.CreateReferenceImageRequest, dict]]): + The request object. Request message for the ``CreateReferenceImage`` method. + parent (:class:`str`): + Required. Resource name of the product in which to + create the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image (:class:`google.cloud.vision_v1p4beta1.types.ReferenceImage`): + Required. The reference image to + create. If an image ID is specified, it + is ignored. + + This corresponds to the ``reference_image`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image_id (:class:`str`): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value + as the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``reference_image_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, reference_image, reference_image_id]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.CreateReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if reference_image is not None: + request.reference_image = reference_image + if reference_image_id is not None: + request.reference_image_id = reference_image_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_reference_image(self, + request: Optional[Union[product_search_service.DeleteReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a reference image. + + The image metadata will be deleted right away, but + search queries against ProductSets containing the image + may still work until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_delete_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + await client.delete_reference_image(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.DeleteReferenceImageRequest, dict]]): + The request object. Request message for the ``DeleteReferenceImage`` method. + name (:class:`str`): + Required. The resource name of the reference image to + delete. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.DeleteReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_reference_images(self, + request: Optional[Union[product_search_service.ListReferenceImagesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListReferenceImagesAsyncPager: + r"""Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_list_reference_images(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.ListReferenceImagesRequest, dict]]): + The request object. Request message for the ``ListReferenceImages`` method. + parent (:class:`str`): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.services.product_search.pagers.ListReferenceImagesAsyncPager: + Response message for the ListReferenceImages method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListReferenceImagesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_reference_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListReferenceImagesAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_reference_image(self, + request: Optional[Union[product_search_service.GetReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_get_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = await client.get_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.GetReferenceImageRequest, dict]]): + The request object. Request message for the ``GetReferenceImage`` method. + name (:class:`str`): + Required. The resource name of the ReferenceImage to + get. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.GetReferenceImageRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_product_to_product_set(self, + request: Optional[Union[product_search_service.AddProductToProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_add_product_to_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.add_product_to_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.AddProductToProductSetRequest, dict]]): + The request object. Request message for the ``AddProductToProductSet`` + method. + name (:class:`str`): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`str`): + Required. The resource name for the Product to be added + to this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.AddProductToProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.add_product_to_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def remove_product_from_product_set(self, + request: Optional[Union[product_search_service.RemoveProductFromProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Removes a Product from the specified ProductSet. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.remove_product_from_product_set(request=request) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.RemoveProductFromProductSetRequest, dict]]): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + name (:class:`str`): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`str`): + Required. The resource name for the Product to be + removed from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.RemoveProductFromProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.remove_product_from_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_products_in_product_set(self, + request: Optional[Union[product_search_service.ListProductsInProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsInProductSetAsyncPager: + r"""Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_list_products_in_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.ListProductsInProductSetRequest, dict]]): + The request object. Request message for the ``ListProductsInProductSet`` + method. + name (:class:`str`): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductsInProductSetAsyncPager: + Response message for the ListProductsInProductSet + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ListProductsInProductSetRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_products_in_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListProductsInProductSetAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def import_product_sets(self, + request: Optional[Union[product_search_service.ImportProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + input_config: Optional[product_search_service.ImportProductSetsInputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p4beta1.ImportProductSetsGcsSource.csv_file_uri]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_import_product_sets(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.ImportProductSetsRequest, dict]]): + The request object. Request message for the ``ImportProductSets`` method. + parent (:class:`str`): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + input_config (:class:`google.cloud.vision_v1p4beta1.types.ImportProductSetsInputConfig`): + Required. The input content for the + list of requests. + + This corresponds to the ``input_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p4beta1.types.ImportProductSetsResponse` + Response message for the ImportProductSets method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, input_config]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.ImportProductSetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if input_config is not None: + request.input_config = input_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + product_search_service.ImportProductSetsResponse, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + async def purge_products(self, + request: Optional[Union[product_search_service.PurgeProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Asynchronous API to delete all Products in a ProductSet or all + Products that are in no ProductSet. + + If a Product is a member of the specified ProductSet in addition + to other ProductSets, the Product will still be deleted. + + It is recommended to not delete the specified ProductSet until + after this operation has completed. It is also recommended to + not add any of the Products involved in the batch delete to a + new ProductSet while this operation is running because those + Products may still end up deleted. + + It's not possible to undo the PurgeProducts operation. + Therefore, it is recommended to keep the csv files used in + ImportProductSets (if that was how you originally built the + Product Set) before starting PurgeProducts, in case you need to + re-import the data after deletion. + + If the plan is to purge all of the Products from a ProductSet + and then re-use the empty ProductSet to re-import new Products + into the empty ProductSet, you must wait until the PurgeProducts + operation has finished for that ProductSet. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + async def sample_purge_products(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.PurgeProductsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.purge_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.vision_v1p4beta1.types.PurgeProductsRequest, dict]]): + The request object. Request message for the ``PurgeProducts`` method. + parent (:class:`str`): + Required. The project and location in which the Products + should be deleted. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + request = product_search_service.PurgeProductsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.purge_products, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ProductSearchAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductSearchAsyncClient", +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/client.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/client.py new file mode 100644 index 00000000..78ba8356 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/client.py @@ -0,0 +1,2718 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +import os +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast + +from google.cloud.vision_v1p4beta1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.vision_v1p4beta1.services.product_search import pagers +from google.cloud.vision_v1p4beta1.types import geometry +from google.cloud.vision_v1p4beta1.types import product_search_service +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ProductSearchGrpcTransport +from .transports.grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .transports.rest import ProductSearchRestTransport + + +class ProductSearchClientMeta(type): + """Metaclass for the ProductSearch client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + _transport_registry = OrderedDict() # type: Dict[str, Type[ProductSearchTransport]] + _transport_registry["grpc"] = ProductSearchGrpcTransport + _transport_registry["grpc_asyncio"] = ProductSearchGrpcAsyncIOTransport + _transport_registry["rest"] = ProductSearchRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ProductSearchTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ProductSearchClient(metaclass=ProductSearchClientMeta): + """Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p4beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p4beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p4beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p4beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + DEFAULT_ENDPOINT = "vision.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductSearchClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ProductSearchTransport: + """Returns the transport used by the client instance. + + Returns: + ProductSearchTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + + @staticmethod + def parse_product_path(path: str) -> Dict[str,str]: + """Parses a product path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_set_path(project: str,location: str,product_set: str,) -> str: + """Returns a fully-qualified product_set string.""" + return "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + + @staticmethod + def parse_product_set_path(path: str) -> Dict[str,str]: + """Parses a product_set path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/productSets/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def reference_image_path(project: str,location: str,product: str,reference_image: str,) -> str: + """Returns a fully-qualified reference_image string.""" + return "projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}".format(project=project, location=location, product=product, reference_image=reference_image, ) + + @staticmethod + def parse_reference_image_path(path: str) -> Dict[str,str]: + """Parses a reference_image path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/products/(?P.+?)/referenceImages/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError("Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError("Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`") + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ProductSearchTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product search client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ProductSearchTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): Custom options for the + client. It won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto switch to the + default mTLS endpoint if client certificate is present, this is + the default value). However, the ``api_endpoint`` property takes + precedence if provided. + (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide client certificate for mutual TLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + if isinstance(client_options, dict): + client_options = client_options_lib.from_dict(client_options) + if client_options is None: + client_options = client_options_lib.ClientOptions() + client_options = cast(client_options_lib.ClientOptions, client_options) + + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(client_options) + + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError("client_options.api_key and credentials are mutually exclusive") + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + if isinstance(transport, ProductSearchTransport): + # transport is a ProductSearchTransport instance. + if credentials or client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = transport + else: + import google.auth._default # type: ignore + + if api_key_value and hasattr(google.auth._default, "get_api_key_credentials"): + credentials = google.auth._default.get_api_key_credentials(api_key_value) + + Transport = type(self).get_transport_class(transport) + self._transport = Transport( + credentials=credentials, + credentials_file=client_options.credentials_file, + host=api_endpoint, + scopes=client_options.scopes, + client_cert_source_for_mtls=client_cert_source_func, + quota_project_id=client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=client_options.api_audience, + ) + + def create_product_set(self, + request: Optional[Union[product_search_service.CreateProductSetRequest, dict]] = None, + *, + parent: Optional[str] = None, + product_set: Optional[product_search_service.ProductSet] = None, + product_set_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_create_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.CreateProductSetRequest, dict]): + The request object. Request message for the ``CreateProductSet`` method. + parent (str): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set (google.cloud.vision_v1p4beta1.types.ProductSet): + Required. The ProductSet to create. + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_set_id (str): + A user-supplied resource id for this ProductSet. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_set_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product_set, product_set_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateProductSetRequest): + request = product_search_service.CreateProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product_set is not None: + request.product_set = product_set + if product_set_id is not None: + request.product_set_id = product_set_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_product_sets(self, + request: Optional[Union[product_search_service.ListProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductSetsPager: + r"""Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_list_product_sets(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.ListProductSetsRequest, dict]): + The request object. Request message for the ``ListProductSets`` method. + parent (str): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductSetsPager: + Response message for the ListProductSets method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductSetsRequest): + request = product_search_service.ListProductSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_product_sets] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductSetsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_product_set(self, + request: Optional[Union[product_search_service.GetProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_get_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = client.get_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.GetProductSetRequest, dict]): + The request object. Request message for the ``GetProductSet`` method. + name (str): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetProductSetRequest): + request = product_search_service.GetProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_product_set(self, + request: Optional[Union[product_search_service.UpdateProductSetRequest, dict]] = None, + *, + product_set: Optional[product_search_service.ProductSet] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ProductSet: + r"""Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_update_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.UpdateProductSetRequest( + ) + + # Make the request + response = client.update_product_set(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.UpdateProductSetRequest, dict]): + The request object. Request message for the ``UpdateProductSet`` method. + product_set (google.cloud.vision_v1p4beta1.types.ProductSet): + Required. The ProductSet resource + which replaces the one on the server. + + This corresponds to the ``product_set`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask path is ``display_name``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product_set, update_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.UpdateProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.UpdateProductSetRequest): + request = product_search_service.UpdateProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product_set is not None: + request.product_set = product_set + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product_set.name", request.product_set.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_product_set(self, + request: Optional[Union[product_search_service.DeleteProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a ProductSet. Products and + ReferenceImages in the ProductSet are not deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_delete_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + client.delete_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.DeleteProductSetRequest, dict]): + The request object. Request message for the ``DeleteProductSet`` method. + name (str): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteProductSetRequest): + request = product_search_service.DeleteProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def create_product(self, + request: Optional[Union[product_search_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[product_search_service.Product] = None, + product_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_create_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.CreateProductRequest, dict]): + The request object. Request message for the ``CreateProduct`` method. + parent (str): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (google.cloud.vision_v1p4beta1.types.Product): + Required. The product to create. + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_id (str): + A user-supplied resource id for this Product. If set, + the server will attempt to use this value as the + resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``product_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, product, product_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateProductRequest): + request = product_search_service.CreateProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if product is not None: + request.product = product + if product_id is not None: + request.product_id = product_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_products(self, + request: Optional[Union[product_search_service.ListProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsPager: + r"""Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_list_products(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.ListProductsRequest, dict]): + The request object. Request message for the ``ListProducts`` method. + parent (str): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductsPager: + Response message for the ListProducts method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductsRequest): + request = product_search_service.ListProductsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_products] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_product(self, + request: Optional[Union[product_search_service.GetProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_get_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.GetProductRequest, dict]): + The request object. Request message for the ``GetProduct`` method. + name (str): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetProductRequest): + request = product_search_service.GetProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_product(self, + request: Optional[Union[product_search_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[product_search_service.Product] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.Product: + r"""Makes changes to a Product resource. Only the ``display_name``, + ``description``, and ``labels`` fields can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_update_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.UpdateProductRequest( + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.UpdateProductRequest, dict]): + The request object. Request message for the ``UpdateProduct`` method. + product (google.cloud.vision_v1p4beta1.types.Product): + Required. The Product resource which + replaces the one on the server. + product.name is immutable. + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that + specifies which fields to update. If update_mask isn't + specified, all mutable fields are to be updated. Valid + mask paths include ``product_labels``, ``display_name``, + and ``description``. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.Product: + A Product contains ReferenceImages. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([product, update_mask]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.UpdateProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.UpdateProductRequest): + request = product_search_service.UpdateProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if product is not None: + request.product = product + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product.name", request.product.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_product(self, + request: Optional[Union[product_search_service.DeleteProductRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a product and its reference + images. + Metadata of the product and all its images will be + deleted right away, but search queries against + ProductSets containing the product may still work until + all related caches are refreshed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_delete_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.DeleteProductRequest, dict]): + The request object. Request message for the ``DeleteProduct`` method. + name (str): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteProductRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteProductRequest): + request = product_search_service.DeleteProductRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_product] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def create_reference_image(self, + request: Optional[Union[product_search_service.CreateReferenceImageRequest, dict]] = None, + *, + parent: Optional[str] = None, + reference_image: Optional[product_search_service.ReferenceImage] = None, + reference_image_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_create_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + reference_image = vision_v1p4beta1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1p4beta1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = client.create_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.CreateReferenceImageRequest, dict]): + The request object. Request message for the ``CreateReferenceImage`` method. + parent (str): + Required. Resource name of the product in which to + create the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image (google.cloud.vision_v1p4beta1.types.ReferenceImage): + Required. The reference image to + create. If an image ID is specified, it + is ignored. + + This corresponds to the ``reference_image`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + reference_image_id (str): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value + as the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + + This corresponds to the ``reference_image_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, reference_image, reference_image_id]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.CreateReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.CreateReferenceImageRequest): + request = product_search_service.CreateReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if reference_image is not None: + request.reference_image = reference_image + if reference_image_id is not None: + request.reference_image_id = reference_image_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_reference_image(self, + request: Optional[Union[product_search_service.DeleteReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Permanently deletes a reference image. + + The image metadata will be deleted right away, but + search queries against ProductSets containing the image + may still work until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_delete_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + client.delete_reference_image(request=request) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.DeleteReferenceImageRequest, dict]): + The request object. Request message for the ``DeleteReferenceImage`` method. + name (str): + Required. The resource name of the reference image to + delete. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.DeleteReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.DeleteReferenceImageRequest): + request = product_search_service.DeleteReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def list_reference_images(self, + request: Optional[Union[product_search_service.ListReferenceImagesRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListReferenceImagesPager: + r"""Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_list_reference_images(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.ListReferenceImagesRequest, dict]): + The request object. Request message for the ``ListReferenceImages`` method. + parent (str): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.services.product_search.pagers.ListReferenceImagesPager: + Response message for the ListReferenceImages method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListReferenceImagesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListReferenceImagesRequest): + request = product_search_service.ListReferenceImagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_reference_images] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListReferenceImagesPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_reference_image(self, + request: Optional[Union[product_search_service.GetReferenceImageRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> product_search_service.ReferenceImage: + r"""Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_get_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = client.get_reference_image(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.GetReferenceImageRequest, dict]): + The request object. Request message for the ``GetReferenceImage`` method. + name (str): + Required. The resource name of the ReferenceImage to + get. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.types.ReferenceImage: + A ReferenceImage represents a product image and its associated metadata, + such as bounding boxes. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.GetReferenceImageRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.GetReferenceImageRequest): + request = product_search_service.GetReferenceImageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_reference_image] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_product_to_product_set(self, + request: Optional[Union[product_search_service.AddProductToProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_add_product_to_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.add_product_to_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.AddProductToProductSetRequest, dict]): + The request object. Request message for the ``AddProductToProductSet`` + method. + name (str): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (str): + Required. The resource name for the Product to be added + to this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.AddProductToProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.AddProductToProductSetRequest): + request = product_search_service.AddProductToProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_product_to_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def remove_product_from_product_set(self, + request: Optional[Union[product_search_service.RemoveProductFromProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + product: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Removes a Product from the specified ProductSet. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.remove_product_from_product_set(request=request) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.RemoveProductFromProductSetRequest, dict]): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + name (str): + Required. The resource name for the ProductSet to + modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (str): + Required. The resource name for the Product to be + removed from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + + This corresponds to the ``product`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, product]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.RemoveProductFromProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.RemoveProductFromProductSetRequest): + request = product_search_service.RemoveProductFromProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if product is not None: + request.product = product + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_product_from_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def list_products_in_product_set(self, + request: Optional[Union[product_search_service.ListProductsInProductSetRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListProductsInProductSetPager: + r"""Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_list_products_in_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.ListProductsInProductSetRequest, dict]): + The request object. Request message for the ``ListProductsInProductSet`` + method. + name (str): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductsInProductSetPager: + Response message for the ListProductsInProductSet + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ListProductsInProductSetRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ListProductsInProductSetRequest): + request = product_search_service.ListProductsInProductSetRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_products_in_product_set] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("name", request.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListProductsInProductSetPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def import_product_sets(self, + request: Optional[Union[product_search_service.ImportProductSetsRequest, dict]] = None, + *, + parent: Optional[str] = None, + input_config: Optional[product_search_service.ImportProductSetsInputConfig] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p4beta1.ImportProductSetsGcsSource.csv_file_uri]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_import_product_sets(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.ImportProductSetsRequest, dict]): + The request object. Request message for the ``ImportProductSets`` method. + parent (str): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + input_config (google.cloud.vision_v1p4beta1.types.ImportProductSetsInputConfig): + Required. The input content for the + list of requests. + + This corresponds to the ``input_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.vision_v1p4beta1.types.ImportProductSetsResponse` + Response message for the ImportProductSets method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, input_config]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.ImportProductSetsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.ImportProductSetsRequest): + request = product_search_service.ImportProductSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if input_config is not None: + request.input_config = input_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_product_sets] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + product_search_service.ImportProductSetsResponse, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + def purge_products(self, + request: Optional[Union[product_search_service.PurgeProductsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Asynchronous API to delete all Products in a ProductSet or all + Products that are in no ProductSet. + + If a Product is a member of the specified ProductSet in addition + to other ProductSets, the Product will still be deleted. + + It is recommended to not delete the specified ProductSet until + after this operation has completed. It is also recommended to + not add any of the Products involved in the batch delete to a + new ProductSet while this operation is running because those + Products may still end up deleted. + + It's not possible to undo the PurgeProducts operation. + Therefore, it is recommended to keep the csv files used in + ImportProductSets (if that was how you originally built the + Product Set) before starting PurgeProducts, in case you need to + re-import the data after deletion. + + If the plan is to purge all of the Products from a ProductSet + and then re-use the empty ProductSet to re-import new Products + into the empty ProductSet, you must wait until the PurgeProducts + operation has finished for that ProductSet. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import vision_v1p4beta1 + + def sample_purge_products(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.PurgeProductsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.purge_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.vision_v1p4beta1.types.PurgeProductsRequest, dict]): + The request object. Request message for the ``PurgeProducts`` method. + parent (str): + Required. The project and location in which the Products + should be deleted. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # Minor optimization to avoid making a copy if the user passes + # in a product_search_service.PurgeProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_search_service.PurgeProductsRequest): + request = product_search_service.PurgeProductsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.purge_products] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("parent", request.parent), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=product_search_service.BatchOperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ProductSearchClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductSearchClient", +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/pagers.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/pagers.py new file mode 100644 index 00000000..a402d5f4 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/pagers.py @@ -0,0 +1,502 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator + +from google.cloud.vision_v1p4beta1.types import product_search_service + + +class ListProductSetsPager: + """A pager for iterating through ``list_product_sets`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p4beta1.types.ListProductSetsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``product_sets`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProductSets`` requests and continue to iterate + through the ``product_sets`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p4beta1.types.ListProductSetsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductSetsResponse], + request: product_search_service.ListProductSetsRequest, + response: product_search_service.ListProductSetsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p4beta1.types.ListProductSetsRequest): + The initial request object. + response (google.cloud.vision_v1p4beta1.types.ListProductSetsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductSetsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductSetsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.ProductSet]: + for page in self.pages: + yield from page.product_sets + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductSetsAsyncPager: + """A pager for iterating through ``list_product_sets`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p4beta1.types.ListProductSetsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``product_sets`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProductSets`` requests and continue to iterate + through the ``product_sets`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p4beta1.types.ListProductSetsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductSetsResponse]], + request: product_search_service.ListProductSetsRequest, + response: product_search_service.ListProductSetsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p4beta1.types.ListProductSetsRequest): + The initial request object. + response (google.cloud.vision_v1p4beta1.types.ListProductSetsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductSetsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductSetsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.ProductSet]: + async def async_generator(): + async for page in self.pages: + for response in page.product_sets: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p4beta1.types.ListProductsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProducts`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p4beta1.types.ListProductsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductsResponse], + request: product_search_service.ListProductsRequest, + response: product_search_service.ListProductsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p4beta1.types.ListProductsRequest): + The initial request object. + response (google.cloud.vision_v1p4beta1.types.ListProductsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.Product]: + for page in self.pages: + yield from page.products + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsAsyncPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p4beta1.types.ListProductsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProducts`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p4beta1.types.ListProductsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductsResponse]], + request: product_search_service.ListProductsRequest, + response: product_search_service.ListProductsResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p4beta1.types.ListProductsRequest): + The initial request object. + response (google.cloud.vision_v1p4beta1.types.ListProductsResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.Product]: + async def async_generator(): + async for page in self.pages: + for response in page.products: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListReferenceImagesPager: + """A pager for iterating through ``list_reference_images`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p4beta1.types.ListReferenceImagesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``reference_images`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListReferenceImages`` requests and continue to iterate + through the ``reference_images`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p4beta1.types.ListReferenceImagesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListReferenceImagesResponse], + request: product_search_service.ListReferenceImagesRequest, + response: product_search_service.ListReferenceImagesResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p4beta1.types.ListReferenceImagesRequest): + The initial request object. + response (google.cloud.vision_v1p4beta1.types.ListReferenceImagesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListReferenceImagesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListReferenceImagesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.ReferenceImage]: + for page in self.pages: + yield from page.reference_images + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListReferenceImagesAsyncPager: + """A pager for iterating through ``list_reference_images`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p4beta1.types.ListReferenceImagesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``reference_images`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListReferenceImages`` requests and continue to iterate + through the ``reference_images`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p4beta1.types.ListReferenceImagesResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListReferenceImagesResponse]], + request: product_search_service.ListReferenceImagesRequest, + response: product_search_service.ListReferenceImagesResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p4beta1.types.ListReferenceImagesRequest): + The initial request object. + response (google.cloud.vision_v1p4beta1.types.ListReferenceImagesResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListReferenceImagesRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListReferenceImagesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.ReferenceImage]: + async def async_generator(): + async for page in self.pages: + for response in page.reference_images: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsInProductSetPager: + """A pager for iterating through ``list_products_in_product_set`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p4beta1.types.ListProductsInProductSetResponse` object, and + provides an ``__iter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListProductsInProductSet`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p4beta1.types.ListProductsInProductSetResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., product_search_service.ListProductsInProductSetResponse], + request: product_search_service.ListProductsInProductSetRequest, + response: product_search_service.ListProductsInProductSetResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p4beta1.types.ListProductsInProductSetRequest): + The initial request object. + response (google.cloud.vision_v1p4beta1.types.ListProductsInProductSetResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsInProductSetRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[product_search_service.ListProductsInProductSetResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[product_search_service.Product]: + for page in self.pages: + yield from page.products + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListProductsInProductSetAsyncPager: + """A pager for iterating through ``list_products_in_product_set`` requests. + + This class thinly wraps an initial + :class:`google.cloud.vision_v1p4beta1.types.ListProductsInProductSetResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``products`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListProductsInProductSet`` requests and continue to iterate + through the ``products`` field on the + corresponding responses. + + All the usual :class:`google.cloud.vision_v1p4beta1.types.ListProductsInProductSetResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + def __init__(self, + method: Callable[..., Awaitable[product_search_service.ListProductsInProductSetResponse]], + request: product_search_service.ListProductsInProductSetRequest, + response: product_search_service.ListProductsInProductSetResponse, + *, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.cloud.vision_v1p4beta1.types.ListProductsInProductSetRequest): + The initial request object. + response (google.cloud.vision_v1p4beta1.types.ListProductsInProductSetResponse): + The initial response object. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = product_search_service.ListProductsInProductSetRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[product_search_service.ListProductsInProductSetResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[product_search_service.Product]: + async def async_generator(): + async for page in self.pages: + for response in page.products: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/__init__.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/__init__.py new file mode 100644 index 00000000..eb2b97bb --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 collections import OrderedDict +from typing import Dict, Type + +from .base import ProductSearchTransport +from .grpc import ProductSearchGrpcTransport +from .grpc_asyncio import ProductSearchGrpcAsyncIOTransport +from .rest import ProductSearchRestTransport +from .rest import ProductSearchRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ProductSearchTransport]] +_transport_registry['grpc'] = ProductSearchGrpcTransport +_transport_registry['grpc_asyncio'] = ProductSearchGrpcAsyncIOTransport +_transport_registry['rest'] = ProductSearchRestTransport + +__all__ = ( + 'ProductSearchTransport', + 'ProductSearchGrpcTransport', + 'ProductSearchGrpcAsyncIOTransport', + 'ProductSearchRestTransport', + 'ProductSearchRestInterceptor', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/base.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/base.py new file mode 100644 index 00000000..50089760 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/base.py @@ -0,0 +1,519 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.vision_v1p4beta1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.vision_v1p4beta1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ProductSearchTransport(abc.ABC): + """Abstract transport class for ProductSearch.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', + ) + + DEFAULT_HOST: str = 'vision.googleapis.com' + def __init__( + self, *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive") + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id + ) + elif credentials is None: + credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience(api_audience if api_audience else host) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ':' not in host: + host += ':443' + self._host = host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_product_set: gapic_v1.method.wrap_method( + self.create_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_product_sets: gapic_v1.method.wrap_method( + self.list_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_product_set: gapic_v1.method.wrap_method( + self.get_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.update_product_set: gapic_v1.method.wrap_method( + self.update_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_product_set: gapic_v1.method.wrap_method( + self.delete_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.create_product: gapic_v1.method.wrap_method( + self.create_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_products: gapic_v1.method.wrap_method( + self.list_products, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_product: gapic_v1.method.wrap_method( + self.get_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.update_product: gapic_v1.method.wrap_method( + self.update_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_product: gapic_v1.method.wrap_method( + self.delete_product, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.create_reference_image: gapic_v1.method.wrap_method( + self.create_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.delete_reference_image: gapic_v1.method.wrap_method( + self.delete_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_reference_images: gapic_v1.method.wrap_method( + self.list_reference_images, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.get_reference_image: gapic_v1.method.wrap_method( + self.get_reference_image, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.add_product_to_product_set: gapic_v1.method.wrap_method( + self.add_product_to_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.remove_product_from_product_set: gapic_v1.method.wrap_method( + self.remove_product_from_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.list_products_in_product_set: gapic_v1.method.wrap_method( + self.list_products_in_product_set, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.import_product_sets: gapic_v1.method.wrap_method( + self.import_product_sets, + default_retry=retries.Retry( +initial=0.1,maximum=60.0,multiplier=1.3, predicate=retries.if_exception_type( + ), + deadline=600.0, + ), + default_timeout=600.0, + client_info=client_info, + ), + self.purge_products: gapic_v1.method.wrap_method( + self.purge_products, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + Union[ + product_search_service.ListProductSetsResponse, + Awaitable[product_search_service.ListProductSetsResponse] + ]]: + raise NotImplementedError() + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + Union[ + product_search_service.ProductSet, + Awaitable[product_search_service.ProductSet] + ]]: + raise NotImplementedError() + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + Union[ + product_search_service.ListProductsResponse, + Awaitable[product_search_service.ListProductsResponse] + ]]: + raise NotImplementedError() + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + Union[ + product_search_service.Product, + Awaitable[product_search_service.Product] + ]]: + raise NotImplementedError() + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + Union[ + product_search_service.ReferenceImage, + Awaitable[product_search_service.ReferenceImage] + ]]: + raise NotImplementedError() + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + Union[ + product_search_service.ListReferenceImagesResponse, + Awaitable[product_search_service.ListReferenceImagesResponse] + ]]: + raise NotImplementedError() + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + Union[ + product_search_service.ReferenceImage, + Awaitable[product_search_service.ReferenceImage] + ]]: + raise NotImplementedError() + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + Union[ + product_search_service.ListProductsInProductSetResponse, + Awaitable[product_search_service.ListProductsInProductSetResponse] + ]]: + raise NotImplementedError() + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def purge_products(self) -> Callable[ + [product_search_service.PurgeProductsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ProductSearchTransport', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/grpc.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/grpc.py new file mode 100644 index 00000000..34968291 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/grpc.py @@ -0,0 +1,926 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore + +from google.cloud.vision_v1p4beta1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO + + +class ProductSearchGrpcTransport(ProductSearchTransport): + """gRPC backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p4beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p4beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p4beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p4beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + _stubs: Dict[str, Callable] + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[grpc.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + channel (Optional[grpc.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service. + """ + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the create product set method over gRPC. + + Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + Returns: + Callable[[~.CreateProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product_set' not in self._stubs: + self._stubs['create_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/CreateProductSet', + request_serializer=product_search_service.CreateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['create_product_set'] + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + product_search_service.ListProductSetsResponse]: + r"""Return a callable for the list product sets method over gRPC. + + Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + Returns: + Callable[[~.ListProductSetsRequest], + ~.ListProductSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_product_sets' not in self._stubs: + self._stubs['list_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ListProductSets', + request_serializer=product_search_service.ListProductSetsRequest.serialize, + response_deserializer=product_search_service.ListProductSetsResponse.deserialize, + ) + return self._stubs['list_product_sets'] + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the get product set method over gRPC. + + Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + Returns: + Callable[[~.GetProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product_set' not in self._stubs: + self._stubs['get_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/GetProductSet', + request_serializer=product_search_service.GetProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['get_product_set'] + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + product_search_service.ProductSet]: + r"""Return a callable for the update product set method over gRPC. + + Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + Returns: + Callable[[~.UpdateProductSetRequest], + ~.ProductSet]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product_set' not in self._stubs: + self._stubs['update_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/UpdateProductSet', + request_serializer=product_search_service.UpdateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['update_product_set'] + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product set method over gRPC. + + Permanently deletes a ProductSet. Products and + ReferenceImages in the ProductSet are not deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + Returns: + Callable[[~.DeleteProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product_set' not in self._stubs: + self._stubs['delete_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/DeleteProductSet', + request_serializer=product_search_service.DeleteProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product_set'] + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + product_search_service.Product]: + r"""Return a callable for the create product method over gRPC. + + Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + Returns: + Callable[[~.CreateProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product' not in self._stubs: + self._stubs['create_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/CreateProduct', + request_serializer=product_search_service.CreateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + product_search_service.ListProductsResponse]: + r"""Return a callable for the list products method over gRPC. + + Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsRequest], + ~.ListProductsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products' not in self._stubs: + self._stubs['list_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ListProducts', + request_serializer=product_search_service.ListProductsRequest.serialize, + response_deserializer=product_search_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + product_search_service.Product]: + r"""Return a callable for the get product method over gRPC. + + Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + Returns: + Callable[[~.GetProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product' not in self._stubs: + self._stubs['get_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/GetProduct', + request_serializer=product_search_service.GetProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + product_search_service.Product]: + r"""Return a callable for the update product method over gRPC. + + Makes changes to a Product resource. Only the ``display_name``, + ``description``, and ``labels`` fields can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + Returns: + Callable[[~.UpdateProductRequest], + ~.Product]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product' not in self._stubs: + self._stubs['update_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/UpdateProduct', + request_serializer=product_search_service.UpdateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product method over gRPC. + + Permanently deletes a product and its reference + images. + Metadata of the product and all its images will be + deleted right away, but search queries against + ProductSets containing the product may still work until + all related caches are refreshed. + + Returns: + Callable[[~.DeleteProductRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product' not in self._stubs: + self._stubs['delete_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/DeleteProduct', + request_serializer=product_search_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + product_search_service.ReferenceImage]: + r"""Return a callable for the create reference image method over gRPC. + + Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + Returns: + Callable[[~.CreateReferenceImageRequest], + ~.ReferenceImage]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_reference_image' not in self._stubs: + self._stubs['create_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/CreateReferenceImage', + request_serializer=product_search_service.CreateReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['create_reference_image'] + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete reference image method over gRPC. + + Permanently deletes a reference image. + + The image metadata will be deleted right away, but + search queries against ProductSets containing the image + may still work until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + Returns: + Callable[[~.DeleteReferenceImageRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_reference_image' not in self._stubs: + self._stubs['delete_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/DeleteReferenceImage', + request_serializer=product_search_service.DeleteReferenceImageRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_reference_image'] + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + product_search_service.ListReferenceImagesResponse]: + r"""Return a callable for the list reference images method over gRPC. + + Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + Returns: + Callable[[~.ListReferenceImagesRequest], + ~.ListReferenceImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_reference_images' not in self._stubs: + self._stubs['list_reference_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ListReferenceImages', + request_serializer=product_search_service.ListReferenceImagesRequest.serialize, + response_deserializer=product_search_service.ListReferenceImagesResponse.deserialize, + ) + return self._stubs['list_reference_images'] + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + product_search_service.ReferenceImage]: + r"""Return a callable for the get reference image method over gRPC. + + Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + Returns: + Callable[[~.GetReferenceImageRequest], + ~.ReferenceImage]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_reference_image' not in self._stubs: + self._stubs['get_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/GetReferenceImage', + request_serializer=product_search_service.GetReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['get_reference_image'] + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the add product to product set method over gRPC. + + Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + Returns: + Callable[[~.AddProductToProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'add_product_to_product_set' not in self._stubs: + self._stubs['add_product_to_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/AddProductToProductSet', + request_serializer=product_search_service.AddProductToProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['add_product_to_product_set'] + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + empty_pb2.Empty]: + r"""Return a callable for the remove product from product + set method over gRPC. + + Removes a Product from the specified ProductSet. + + Returns: + Callable[[~.RemoveProductFromProductSetRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'remove_product_from_product_set' not in self._stubs: + self._stubs['remove_product_from_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/RemoveProductFromProductSet', + request_serializer=product_search_service.RemoveProductFromProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['remove_product_from_product_set'] + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + product_search_service.ListProductsInProductSetResponse]: + r"""Return a callable for the list products in product set method over gRPC. + + Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsInProductSetRequest], + ~.ListProductsInProductSetResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products_in_product_set' not in self._stubs: + self._stubs['list_products_in_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ListProductsInProductSet', + request_serializer=product_search_service.ListProductsInProductSetRequest.serialize, + response_deserializer=product_search_service.ListProductsInProductSetResponse.deserialize, + ) + return self._stubs['list_products_in_product_set'] + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import product sets method over gRPC. + + Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p4beta1.ImportProductSetsGcsSource.csv_file_uri]. + + Returns: + Callable[[~.ImportProductSetsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'import_product_sets' not in self._stubs: + self._stubs['import_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ImportProductSets', + request_serializer=product_search_service.ImportProductSetsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_product_sets'] + + @property + def purge_products(self) -> Callable[ + [product_search_service.PurgeProductsRequest], + operations_pb2.Operation]: + r"""Return a callable for the purge products method over gRPC. + + Asynchronous API to delete all Products in a ProductSet or all + Products that are in no ProductSet. + + If a Product is a member of the specified ProductSet in addition + to other ProductSets, the Product will still be deleted. + + It is recommended to not delete the specified ProductSet until + after this operation has completed. It is also recommended to + not add any of the Products involved in the batch delete to a + new ProductSet while this operation is running because those + Products may still end up deleted. + + It's not possible to undo the PurgeProducts operation. + Therefore, it is recommended to keep the csv files used in + ImportProductSets (if that was how you originally built the + Product Set) before starting PurgeProducts, in case you need to + re-import the data after deletion. + + If the plan is to purge all of the Products from a ProductSet + and then re-use the empty ProductSet to re-import new Products + into the empty ProductSet, you must wait until the PurgeProducts + operation has finished for that ProductSet. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) + + Returns: + Callable[[~.PurgeProductsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'purge_products' not in self._stubs: + self._stubs['purge_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/PurgeProducts', + request_serializer=product_search_service.PurgeProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_products'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ProductSearchGrpcTransport', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/grpc_asyncio.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/grpc_asyncio.py new file mode 100644 index 00000000..15d54157 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/grpc_asyncio.py @@ -0,0 +1,925 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.vision_v1p4beta1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO +from .grpc import ProductSearchGrpcTransport + + +class ProductSearchGrpcAsyncIOTransport(ProductSearchTransport): + """gRPC AsyncIO backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p4beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p4beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p4beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p4beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel(cls, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs + ) + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[aio.Channel] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + + if channel: + # Ignore credentials if a channel was passed. + credentials = False + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the create product set method over gRPC. + + Creates and returns a new ProductSet resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing, or is + longer than 4096 characters. + + Returns: + Callable[[~.CreateProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product_set' not in self._stubs: + self._stubs['create_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/CreateProductSet', + request_serializer=product_search_service.CreateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['create_product_set'] + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + Awaitable[product_search_service.ListProductSetsResponse]]: + r"""Return a callable for the list product sets method over gRPC. + + Lists ProductSets in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100, or + less than 1. + + Returns: + Callable[[~.ListProductSetsRequest], + Awaitable[~.ListProductSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_product_sets' not in self._stubs: + self._stubs['list_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ListProductSets', + request_serializer=product_search_service.ListProductSetsRequest.serialize, + response_deserializer=product_search_service.ListProductSetsResponse.deserialize, + ) + return self._stubs['list_product_sets'] + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the get product set method over gRPC. + + Gets information associated with a ProductSet. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + + Returns: + Callable[[~.GetProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product_set' not in self._stubs: + self._stubs['get_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/GetProductSet', + request_serializer=product_search_service.GetProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['get_product_set'] + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + Awaitable[product_search_service.ProductSet]]: + r"""Return a callable for the update product set method over gRPC. + + Makes changes to a ProductSet resource. Only display_name can be + updated currently. + + Possible errors: + + - Returns NOT_FOUND if the ProductSet does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but missing from the request or longer than 4096 + characters. + + Returns: + Callable[[~.UpdateProductSetRequest], + Awaitable[~.ProductSet]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product_set' not in self._stubs: + self._stubs['update_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/UpdateProductSet', + request_serializer=product_search_service.UpdateProductSetRequest.serialize, + response_deserializer=product_search_service.ProductSet.deserialize, + ) + return self._stubs['update_product_set'] + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product set method over gRPC. + + Permanently deletes a ProductSet. Products and + ReferenceImages in the ProductSet are not deleted. + + The actual image files are not deleted from Google Cloud + Storage. + + Returns: + Callable[[~.DeleteProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product_set' not in self._stubs: + self._stubs['delete_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/DeleteProductSet', + request_serializer=product_search_service.DeleteProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product_set'] + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the create product method over gRPC. + + Creates and returns a new product resource. + + Possible errors: + + - Returns INVALID_ARGUMENT if display_name is missing or longer + than 4096 characters. + - Returns INVALID_ARGUMENT if description is longer than 4096 + characters. + - Returns INVALID_ARGUMENT if product_category is missing or + invalid. + + Returns: + Callable[[~.CreateProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_product' not in self._stubs: + self._stubs['create_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/CreateProduct', + request_serializer=product_search_service.CreateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + Awaitable[product_search_service.ListProductsResponse]]: + r"""Return a callable for the list products method over gRPC. + + Lists products in an unspecified order. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsRequest], + Awaitable[~.ListProductsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products' not in self._stubs: + self._stubs['list_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ListProducts', + request_serializer=product_search_service.ListProductsRequest.serialize, + response_deserializer=product_search_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the get product method over gRPC. + + Gets information associated with a Product. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + + Returns: + Callable[[~.GetProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_product' not in self._stubs: + self._stubs['get_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/GetProduct', + request_serializer=product_search_service.GetProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + Awaitable[product_search_service.Product]]: + r"""Return a callable for the update product method over gRPC. + + Makes changes to a Product resource. Only the ``display_name``, + ``description``, and ``labels`` fields can be updated right now. + + If labels are updated, the change will not be reflected in + queries until the next index time. + + Possible errors: + + - Returns NOT_FOUND if the Product does not exist. + - Returns INVALID_ARGUMENT if display_name is present in + update_mask but is missing from the request or longer than + 4096 characters. + - Returns INVALID_ARGUMENT if description is present in + update_mask but is longer than 4096 characters. + - Returns INVALID_ARGUMENT if product_category is present in + update_mask. + + Returns: + Callable[[~.UpdateProductRequest], + Awaitable[~.Product]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'update_product' not in self._stubs: + self._stubs['update_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/UpdateProduct', + request_serializer=product_search_service.UpdateProductRequest.serialize, + response_deserializer=product_search_service.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product method over gRPC. + + Permanently deletes a product and its reference + images. + Metadata of the product and all its images will be + deleted right away, but search queries against + ProductSets containing the product may still work until + all related caches are refreshed. + + Returns: + Callable[[~.DeleteProductRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_product' not in self._stubs: + self._stubs['delete_product'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/DeleteProduct', + request_serializer=product_search_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + Awaitable[product_search_service.ReferenceImage]]: + r"""Return a callable for the create reference image method over gRPC. + + Creates and returns a new ReferenceImage resource. + + The ``bounding_poly`` field is optional. If ``bounding_poly`` is + not specified, the system will try to detect regions of interest + in the image that are compatible with the product_category on + the parent product. If it is specified, detection is ALWAYS + skipped. The system converts polygons into non-rotated + rectangles. + + Note that the pipeline will resize the image if the image + resolution is too large to process (above 50MP). + + Possible errors: + + - Returns INVALID_ARGUMENT if the image_uri is missing or + longer than 4096 characters. + - Returns INVALID_ARGUMENT if the product does not exist. + - Returns INVALID_ARGUMENT if bounding_poly is not provided, + and nothing compatible with the parent product's + product_category is detected. + - Returns INVALID_ARGUMENT if bounding_poly contains more than + 10 polygons. + + Returns: + Callable[[~.CreateReferenceImageRequest], + Awaitable[~.ReferenceImage]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'create_reference_image' not in self._stubs: + self._stubs['create_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/CreateReferenceImage', + request_serializer=product_search_service.CreateReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['create_reference_image'] + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete reference image method over gRPC. + + Permanently deletes a reference image. + + The image metadata will be deleted right away, but + search queries against ProductSets containing the image + may still work until all related caches are refreshed. + + The actual image files are not deleted from Google Cloud + Storage. + + Returns: + Callable[[~.DeleteReferenceImageRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'delete_reference_image' not in self._stubs: + self._stubs['delete_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/DeleteReferenceImage', + request_serializer=product_search_service.DeleteReferenceImageRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_reference_image'] + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + Awaitable[product_search_service.ListReferenceImagesResponse]]: + r"""Return a callable for the list reference images method over gRPC. + + Lists reference images. + + Possible errors: + + - Returns NOT_FOUND if the parent product does not exist. + - Returns INVALID_ARGUMENT if the page_size is greater than + 100, or less than 1. + + Returns: + Callable[[~.ListReferenceImagesRequest], + Awaitable[~.ListReferenceImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_reference_images' not in self._stubs: + self._stubs['list_reference_images'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ListReferenceImages', + request_serializer=product_search_service.ListReferenceImagesRequest.serialize, + response_deserializer=product_search_service.ListReferenceImagesResponse.deserialize, + ) + return self._stubs['list_reference_images'] + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + Awaitable[product_search_service.ReferenceImage]]: + r"""Return a callable for the get reference image method over gRPC. + + Gets information associated with a ReferenceImage. + + Possible errors: + + - Returns NOT_FOUND if the specified image does not exist. + + Returns: + Callable[[~.GetReferenceImageRequest], + Awaitable[~.ReferenceImage]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'get_reference_image' not in self._stubs: + self._stubs['get_reference_image'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/GetReferenceImage', + request_serializer=product_search_service.GetReferenceImageRequest.serialize, + response_deserializer=product_search_service.ReferenceImage.deserialize, + ) + return self._stubs['get_reference_image'] + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the add product to product set method over gRPC. + + Adds a Product to the specified ProductSet. If the Product is + already present, no change is made. + + One Product can be added to at most 100 ProductSets. + + Possible errors: + + - Returns NOT_FOUND if the Product or the ProductSet doesn't + exist. + + Returns: + Callable[[~.AddProductToProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'add_product_to_product_set' not in self._stubs: + self._stubs['add_product_to_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/AddProductToProductSet', + request_serializer=product_search_service.AddProductToProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['add_product_to_product_set'] + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the remove product from product + set method over gRPC. + + Removes a Product from the specified ProductSet. + + Returns: + Callable[[~.RemoveProductFromProductSetRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'remove_product_from_product_set' not in self._stubs: + self._stubs['remove_product_from_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/RemoveProductFromProductSet', + request_serializer=product_search_service.RemoveProductFromProductSetRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['remove_product_from_product_set'] + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + Awaitable[product_search_service.ListProductsInProductSetResponse]]: + r"""Return a callable for the list products in product set method over gRPC. + + Lists the Products in a ProductSet, in an unspecified order. If + the ProductSet does not exist, the products field of the + response will be empty. + + Possible errors: + + - Returns INVALID_ARGUMENT if page_size is greater than 100 or + less than 1. + + Returns: + Callable[[~.ListProductsInProductSetRequest], + Awaitable[~.ListProductsInProductSetResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'list_products_in_product_set' not in self._stubs: + self._stubs['list_products_in_product_set'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ListProductsInProductSet', + request_serializer=product_search_service.ListProductsInProductSetRequest.serialize, + response_deserializer=product_search_service.ListProductsInProductSetResponse.deserialize, + ) + return self._stubs['list_products_in_product_set'] + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import product sets method over gRPC. + + Asynchronous API that imports a list of reference images to + specified product sets based on a list of image information. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) ``Operation.response`` + contains ``ImportProductSetsResponse``. (results) + + The input source of this method is a csv file on Google Cloud + Storage. For the format of the csv file please see + [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1p4beta1.ImportProductSetsGcsSource.csv_file_uri]. + + Returns: + Callable[[~.ImportProductSetsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'import_product_sets' not in self._stubs: + self._stubs['import_product_sets'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/ImportProductSets', + request_serializer=product_search_service.ImportProductSetsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_product_sets'] + + @property + def purge_products(self) -> Callable[ + [product_search_service.PurgeProductsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the purge products method over gRPC. + + Asynchronous API to delete all Products in a ProductSet or all + Products that are in no ProductSet. + + If a Product is a member of the specified ProductSet in addition + to other ProductSets, the Product will still be deleted. + + It is recommended to not delete the specified ProductSet until + after this operation has completed. It is also recommended to + not add any of the Products involved in the batch delete to a + new ProductSet while this operation is running because those + Products may still end up deleted. + + It's not possible to undo the PurgeProducts operation. + Therefore, it is recommended to keep the csv files used in + ImportProductSets (if that was how you originally built the + Product Set) before starting PurgeProducts, in case you need to + re-import the data after deletion. + + If the plan is to purge all of the Products from a ProductSet + and then re-use the empty ProductSet to re-import new Products + into the empty ProductSet, you must wait until the PurgeProducts + operation has finished for that ProductSet. + + The [google.longrunning.Operation][google.longrunning.Operation] + API can be used to keep track of the progress and results of the + request. ``Operation.metadata`` contains + ``BatchOperationMetadata``. (progress) + + Returns: + Callable[[~.PurgeProductsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'purge_products' not in self._stubs: + self._stubs['purge_products'] = self.grpc_channel.unary_unary( + '/google.cloud.vision.v1p4beta1.ProductSearch/PurgeProducts', + request_serializer=product_search_service.PurgeProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_products'] + + def close(self): + return self.grpc_channel.close() + + +__all__ = ( + 'ProductSearchGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/rest.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/rest.py new file mode 100644 index 00000000..8d4ab7cb --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/services/product_search/transports/rest.py @@ -0,0 +1,2306 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 google.auth.transport.requests import AuthorizedSession # type: ignore +import json # type: ignore +import grpc # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.api_core import rest_helpers +from google.api_core import rest_streaming +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from google.api_core import operations_v1 +from requests import __version__ as requests_version +import dataclasses +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + + +from google.cloud.vision_v1p4beta1.types import product_search_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ProductSearchTransport, DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=requests_version, +) + + +class ProductSearchRestInterceptor: + """Interceptor for ProductSearch. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ProductSearchRestTransport. + + .. code-block:: python + class MyCustomProductSearchInterceptor(ProductSearchRestInterceptor): + def pre_add_product_to_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_create_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_reference_image(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_reference_image(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_reference_image(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_product_sets(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_product_sets(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_products(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_products(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_product_sets(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_product_sets(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_products_in_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_products_in_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_reference_images(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_reference_images(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_purge_products(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_purge_products(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_product_from_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_update_product(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_product(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_product_set(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_product_set(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ProductSearchRestTransport(interceptor=MyCustomProductSearchInterceptor()) + client = ProductSearchClient(transport=transport) + + + """ + def pre_add_product_to_product_set(self, request: product_search_service.AddProductToProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.AddProductToProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_product_to_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_create_product(self, request: product_search_service.CreateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for create_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_create_product_set(self, request: product_search_service.CreateProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for create_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_create_reference_image(self, request: product_search_service.CreateReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.CreateReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_create_reference_image(self, response: product_search_service.ReferenceImage) -> product_search_service.ReferenceImage: + """Post-rpc interceptor for create_reference_image + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_delete_product(self, request: product_search_service.DeleteProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_delete_product_set(self, request: product_search_service.DeleteProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_delete_reference_image(self, request: product_search_service.DeleteReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.DeleteReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_get_product(self, request: product_search_service.GetProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for get_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_get_product_set(self, request: product_search_service.GetProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for get_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_get_reference_image(self, request: product_search_service.GetReferenceImageRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.GetReferenceImageRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_reference_image + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_get_reference_image(self, response: product_search_service.ReferenceImage) -> product_search_service.ReferenceImage: + """Post-rpc interceptor for get_reference_image + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_import_product_sets(self, request: product_search_service.ImportProductSetsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ImportProductSetsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_product_sets + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_import_product_sets(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_product_sets + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_products(self, request: product_search_service.ListProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_products + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_products(self, response: product_search_service.ListProductsResponse) -> product_search_service.ListProductsResponse: + """Post-rpc interceptor for list_products + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_product_sets(self, request: product_search_service.ListProductSetsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductSetsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_product_sets + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_product_sets(self, response: product_search_service.ListProductSetsResponse) -> product_search_service.ListProductSetsResponse: + """Post-rpc interceptor for list_product_sets + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_products_in_product_set(self, request: product_search_service.ListProductsInProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListProductsInProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_products_in_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_products_in_product_set(self, response: product_search_service.ListProductsInProductSetResponse) -> product_search_service.ListProductsInProductSetResponse: + """Post-rpc interceptor for list_products_in_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_list_reference_images(self, request: product_search_service.ListReferenceImagesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.ListReferenceImagesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_reference_images + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_list_reference_images(self, response: product_search_service.ListReferenceImagesResponse) -> product_search_service.ListReferenceImagesResponse: + """Post-rpc interceptor for list_reference_images + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_purge_products(self, request: product_search_service.PurgeProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.PurgeProductsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for purge_products + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_purge_products(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for purge_products + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_remove_product_from_product_set(self, request: product_search_service.RemoveProductFromProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.RemoveProductFromProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_product_from_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def pre_update_product(self, request: product_search_service.UpdateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.UpdateProductRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_product + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_update_product(self, response: product_search_service.Product) -> product_search_service.Product: + """Post-rpc interceptor for update_product + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + def pre_update_product_set(self, request: product_search_service.UpdateProductSetRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_search_service.UpdateProductSetRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_product_set + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductSearch server. + """ + return request, metadata + + def post_update_product_set(self, response: product_search_service.ProductSet) -> product_search_service.ProductSet: + """Post-rpc interceptor for update_product_set + + Override in a subclass to manipulate the response + after it is returned by the ProductSearch server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ProductSearchRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ProductSearchRestInterceptor + + +class ProductSearchRestTransport(ProductSearchTransport): + """REST backend transport for ProductSearch. + + Manages Products and ProductSets of reference images for use in + product search. It uses the following resource model: + + - The API has a collection of + [ProductSet][google.cloud.vision.v1p4beta1.ProductSet] resources, + named ``projects/*/locations/*/productSets/*``, which acts as a + way to put different products into groups to limit + identification. + + In parallel, + + - The API has a collection of + [Product][google.cloud.vision.v1p4beta1.Product] resources, named + ``projects/*/locations/*/products/*`` + + - Each [Product][google.cloud.vision.v1p4beta1.Product] has a + collection of + [ReferenceImage][google.cloud.vision.v1p4beta1.ReferenceImage] + resources, named + ``projects/*/locations/*/products/*/referenceImages/*`` + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + + """ + + def __init__(self, *, + host: str = 'vision.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[ + ], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + interceptor: Optional[ProductSearchRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + + credentials_file (Optional[str]): A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if ``channel`` is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError(f"Unexpected hostname structure: {host}") # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ProductSearchRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1p4beta1") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AddProductToProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("AddProductToProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.AddProductToProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the add product to product + set method over HTTP. + + Args: + request (~.product_search_service.AddProductToProductSetRequest): + The request object. Request message for the ``AddProductToProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/productSets/*}:addProduct', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_product_to_product_set(request, metadata) + pb_request = product_search_service.AddProductToProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _CreateProduct(ProductSearchRestStub): + def __hash__(self): + return hash("CreateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the create product method over HTTP. + + Args: + request (~.product_search_service.CreateProductRequest): + The request object. Request message for the ``CreateProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/{parent=projects/*/locations/*}/products', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_create_product(request, metadata) + pb_request = product_search_service.CreateProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product(resp) + return resp + + class _CreateProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("CreateProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the create product set method over HTTP. + + Args: + request (~.product_search_service.CreateProductSetRequest): + The request object. Request message for the ``CreateProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/{parent=projects/*/locations/*}/productSets', + 'body': 'product_set', + }, + ] + request, metadata = self._interceptor.pre_create_product_set(request, metadata) + pb_request = product_search_service.CreateProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product_set(resp) + return resp + + class _CreateReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("CreateReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.CreateReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ReferenceImage: + r"""Call the create reference image method over HTTP. + + Args: + request (~.product_search_service.CreateReferenceImageRequest): + The request object. Request message for the ``CreateReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ReferenceImage: + A ``ReferenceImage`` represents a product image and its + associated metadata, such as bounding boxes. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/{parent=projects/*/locations/*/products/*}/referenceImages', + 'body': 'reference_image', + }, + ] + request, metadata = self._interceptor.pre_create_reference_image(request, metadata) + pb_request = product_search_service.CreateReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ReferenceImage() + pb_resp = product_search_service.ReferenceImage.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_reference_image(resp) + return resp + + class _DeleteProduct(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete product method over HTTP. + + Args: + request (~.product_search_service.DeleteProductRequest): + The request object. Request message for the ``DeleteProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/products/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_product(request, metadata) + pb_request = product_search_service.DeleteProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete product set method over HTTP. + + Args: + request (~.product_search_service.DeleteProductSetRequest): + The request object. Request message for the ``DeleteProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/productSets/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_product_set(request, metadata) + pb_request = product_search_service.DeleteProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("DeleteReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.DeleteReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete reference image method over HTTP. + + Args: + request (~.product_search_service.DeleteReferenceImageRequest): + The request object. Request message for the ``DeleteReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/products/*/referenceImages/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_reference_image(request, metadata) + pb_request = product_search_service.DeleteReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _GetProduct(ProductSearchRestStub): + def __hash__(self): + return hash("GetProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the get product method over HTTP. + + Args: + request (~.product_search_service.GetProductRequest): + The request object. Request message for the ``GetProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/products/*}', + }, + ] + request, metadata = self._interceptor.pre_get_product(request, metadata) + pb_request = product_search_service.GetProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product(resp) + return resp + + class _GetProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("GetProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the get product set method over HTTP. + + Args: + request (~.product_search_service.GetProductSetRequest): + The request object. Request message for the ``GetProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/productSets/*}', + }, + ] + request, metadata = self._interceptor.pre_get_product_set(request, metadata) + pb_request = product_search_service.GetProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product_set(resp) + return resp + + class _GetReferenceImage(ProductSearchRestStub): + def __hash__(self): + return hash("GetReferenceImage") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.GetReferenceImageRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ReferenceImage: + r"""Call the get reference image method over HTTP. + + Args: + request (~.product_search_service.GetReferenceImageRequest): + The request object. Request message for the ``GetReferenceImage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ReferenceImage: + A ``ReferenceImage`` represents a product image and its + associated metadata, such as bounding boxes. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/products/*/referenceImages/*}', + }, + ] + request, metadata = self._interceptor.pre_get_reference_image(request, metadata) + pb_request = product_search_service.GetReferenceImageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ReferenceImage() + pb_resp = product_search_service.ReferenceImage.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_reference_image(resp) + return resp + + class _ImportProductSets(ProductSearchRestStub): + def __hash__(self): + return hash("ImportProductSets") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ImportProductSetsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import product sets method over HTTP. + + Args: + request (~.product_search_service.ImportProductSetsRequest): + The request object. Request message for the ``ImportProductSets`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/{parent=projects/*/locations/*}/productSets:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_product_sets(request, metadata) + pb_request = product_search_service.ImportProductSetsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_import_product_sets(resp) + return resp + + class _ListProducts(ProductSearchRestStub): + def __hash__(self): + return hash("ListProducts") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductsResponse: + r"""Call the list products method over HTTP. + + Args: + request (~.product_search_service.ListProductsRequest): + The request object. Request message for the ``ListProducts`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductsResponse: + Response message for the ``ListProducts`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p4beta1/{parent=projects/*/locations/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products(request, metadata) + pb_request = product_search_service.ListProductsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductsResponse() + pb_resp = product_search_service.ListProductsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_products(resp) + return resp + + class _ListProductSets(ProductSearchRestStub): + def __hash__(self): + return hash("ListProductSets") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductSetsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductSetsResponse: + r"""Call the list product sets method over HTTP. + + Args: + request (~.product_search_service.ListProductSetsRequest): + The request object. Request message for the ``ListProductSets`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductSetsResponse: + Response message for the ``ListProductSets`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p4beta1/{parent=projects/*/locations/*}/productSets', + }, + ] + request, metadata = self._interceptor.pre_list_product_sets(request, metadata) + pb_request = product_search_service.ListProductSetsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductSetsResponse() + pb_resp = product_search_service.ListProductSetsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_product_sets(resp) + return resp + + class _ListProductsInProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("ListProductsInProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListProductsInProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListProductsInProductSetResponse: + r"""Call the list products in product + set method over HTTP. + + Args: + request (~.product_search_service.ListProductsInProductSetRequest): + The request object. Request message for the ``ListProductsInProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListProductsInProductSetResponse: + Response message for the ``ListProductsInProductSet`` + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/productSets/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products_in_product_set(request, metadata) + pb_request = product_search_service.ListProductsInProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListProductsInProductSetResponse() + pb_resp = product_search_service.ListProductsInProductSetResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_products_in_product_set(resp) + return resp + + class _ListReferenceImages(ProductSearchRestStub): + def __hash__(self): + return hash("ListReferenceImages") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.ListReferenceImagesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ListReferenceImagesResponse: + r"""Call the list reference images method over HTTP. + + Args: + request (~.product_search_service.ListReferenceImagesRequest): + The request object. Request message for the ``ListReferenceImages`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ListReferenceImagesResponse: + Response message for the ``ListReferenceImages`` method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1p4beta1/{parent=projects/*/locations/*/products/*}/referenceImages', + }, + ] + request, metadata = self._interceptor.pre_list_reference_images(request, metadata) + pb_request = product_search_service.ListReferenceImagesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ListReferenceImagesResponse() + pb_resp = product_search_service.ListReferenceImagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_reference_images(resp) + return resp + + class _PurgeProducts(ProductSearchRestStub): + def __hash__(self): + return hash("PurgeProducts") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.PurgeProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the purge products method over HTTP. + + Args: + request (~.product_search_service.PurgeProductsRequest): + The request object. Request message for the ``PurgeProducts`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/{parent=projects/*/locations/*}/products:purge', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_purge_products(request, metadata) + pb_request = product_search_service.PurgeProductsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_purge_products(resp) + return resp + + class _RemoveProductFromProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("RemoveProductFromProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.RemoveProductFromProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the remove product from + product set method over HTTP. + + Args: + request (~.product_search_service.RemoveProductFromProductSetRequest): + The request object. Request message for the ``RemoveProductFromProductSet`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1p4beta1/{name=projects/*/locations/*/productSets/*}:removeProduct', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_product_from_product_set(request, metadata) + pb_request = product_search_service.RemoveProductFromProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _UpdateProduct(ProductSearchRestStub): + def __hash__(self): + return hash("UpdateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.UpdateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.Product: + r"""Call the update product method over HTTP. + + Args: + request (~.product_search_service.UpdateProductRequest): + The request object. Request message for the ``UpdateProduct`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.Product: + A Product contains ReferenceImages. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v1p4beta1/{product.name=projects/*/locations/*/products/*}', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_update_product(request, metadata) + pb_request = product_search_service.UpdateProductRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.Product() + pb_resp = product_search_service.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product(resp) + return resp + + class _UpdateProductSet(ProductSearchRestStub): + def __hash__(self): + return hash("UpdateProductSet") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return {k: v for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() if k not in message_dict} + + def __call__(self, + request: product_search_service.UpdateProductSetRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_search_service.ProductSet: + r"""Call the update product set method over HTTP. + + Args: + request (~.product_search_service.UpdateProductSetRequest): + The request object. Request message for the ``UpdateProductSet`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.product_search_service.ProductSet: + A ProductSet contains Products. A + ProductSet can contain a maximum of 1 + million reference images. If the limit + is exceeded, periodic indexing will + fail. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v1p4beta1/{product_set.name=projects/*/locations/*/productSets/*}', + 'body': 'product_set', + }, + ] + request, metadata = self._interceptor.pre_update_product_set(request, metadata) + pb_request = product_search_service.UpdateProductSetRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + including_default_value_fields=False, + use_integers_for_enums=True + ) + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + including_default_value_fields=False, + use_integers_for_enums=True, + )) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = product_search_service.ProductSet() + pb_resp = product_search_service.ProductSet.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product_set(resp) + return resp + + @property + def add_product_to_product_set(self) -> Callable[ + [product_search_service.AddProductToProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._AddProductToProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product(self) -> Callable[ + [product_search_service.CreateProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product_set(self) -> Callable[ + [product_search_service.CreateProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_reference_image(self) -> Callable[ + [product_search_service.CreateReferenceImageRequest], + product_search_service.ReferenceImage]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_product(self) -> Callable[ + [product_search_service.DeleteProductRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_product_set(self) -> Callable[ + [product_search_service.DeleteProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_reference_image(self) -> Callable[ + [product_search_service.DeleteReferenceImageRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_product(self) -> Callable[ + [product_search_service.GetProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_product_set(self) -> Callable[ + [product_search_service.GetProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_reference_image(self) -> Callable[ + [product_search_service.GetReferenceImageRequest], + product_search_service.ReferenceImage]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetReferenceImage(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_product_sets(self) -> Callable[ + [product_search_service.ImportProductSetsRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ImportProductSets(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products(self) -> Callable[ + [product_search_service.ListProductsRequest], + product_search_service.ListProductsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProducts(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_product_sets(self) -> Callable[ + [product_search_service.ListProductSetsRequest], + product_search_service.ListProductSetsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProductSets(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products_in_product_set(self) -> Callable[ + [product_search_service.ListProductsInProductSetRequest], + product_search_service.ListProductsInProductSetResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListProductsInProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_reference_images(self) -> Callable[ + [product_search_service.ListReferenceImagesRequest], + product_search_service.ListReferenceImagesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListReferenceImages(self._session, self._host, self._interceptor) # type: ignore + + @property + def purge_products(self) -> Callable[ + [product_search_service.PurgeProductsRequest], + operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._PurgeProducts(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_product_from_product_set(self) -> Callable[ + [product_search_service.RemoveProductFromProductSetRequest], + empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._RemoveProductFromProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product(self) -> Callable[ + [product_search_service.UpdateProductRequest], + product_search_service.Product]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateProduct(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product_set(self) -> Callable[ + [product_search_service.UpdateProductSetRequest], + product_search_service.ProductSet]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateProductSet(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ProductSearchRestTransport', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/__init__.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/__init__.py new file mode 100644 index 00000000..3d8f97f7 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/__init__.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 .face import ( + Celebrity, + FaceRecognitionParams, + FaceRecognitionResult, +) +from .geometry import ( + BoundingPoly, + NormalizedVertex, + Position, + Vertex, +) +from .image_annotator import ( + AnnotateFileRequest, + AnnotateFileResponse, + AnnotateImageRequest, + AnnotateImageResponse, + AsyncAnnotateFileRequest, + AsyncAnnotateFileResponse, + AsyncBatchAnnotateFilesRequest, + AsyncBatchAnnotateFilesResponse, + AsyncBatchAnnotateImagesRequest, + AsyncBatchAnnotateImagesResponse, + BatchAnnotateFilesRequest, + BatchAnnotateFilesResponse, + BatchAnnotateImagesRequest, + BatchAnnotateImagesResponse, + ColorInfo, + CropHint, + CropHintsAnnotation, + CropHintsParams, + DominantColorsAnnotation, + EntityAnnotation, + FaceAnnotation, + Feature, + GcsDestination, + GcsSource, + Image, + ImageAnnotationContext, + ImageContext, + ImageProperties, + ImageSource, + InputConfig, + LatLongRect, + LocalizedObjectAnnotation, + LocationInfo, + OperationMetadata, + OutputConfig, + Property, + SafeSearchAnnotation, + TextDetectionParams, + WebDetectionParams, + Likelihood, +) +from .product_search import ( + ProductSearchParams, + ProductSearchResults, +) +from .product_search_service import ( + AddProductToProductSetRequest, + BatchOperationMetadata, + CreateProductRequest, + CreateProductSetRequest, + CreateReferenceImageRequest, + DeleteProductRequest, + DeleteProductSetRequest, + DeleteReferenceImageRequest, + GetProductRequest, + GetProductSetRequest, + GetReferenceImageRequest, + ImportProductSetsGcsSource, + ImportProductSetsInputConfig, + ImportProductSetsRequest, + ImportProductSetsResponse, + ListProductSetsRequest, + ListProductSetsResponse, + ListProductsInProductSetRequest, + ListProductsInProductSetResponse, + ListProductsRequest, + ListProductsResponse, + ListReferenceImagesRequest, + ListReferenceImagesResponse, + Product, + ProductSet, + ProductSetPurgeConfig, + PurgeProductsRequest, + ReferenceImage, + RemoveProductFromProductSetRequest, + UpdateProductRequest, + UpdateProductSetRequest, +) +from .text_annotation import ( + Block, + Page, + Paragraph, + Symbol, + TextAnnotation, + Word, +) +from .web_detection import ( + WebDetection, +) + +__all__ = ( + 'Celebrity', + 'FaceRecognitionParams', + 'FaceRecognitionResult', + 'BoundingPoly', + 'NormalizedVertex', + 'Position', + 'Vertex', + 'AnnotateFileRequest', + 'AnnotateFileResponse', + 'AnnotateImageRequest', + 'AnnotateImageResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'AsyncBatchAnnotateImagesRequest', + 'AsyncBatchAnnotateImagesResponse', + 'BatchAnnotateFilesRequest', + 'BatchAnnotateFilesResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'ColorInfo', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'DominantColorsAnnotation', + 'EntityAnnotation', + 'FaceAnnotation', + 'Feature', + 'GcsDestination', + 'GcsSource', + 'Image', + 'ImageAnnotationContext', + 'ImageContext', + 'ImageProperties', + 'ImageSource', + 'InputConfig', + 'LatLongRect', + 'LocalizedObjectAnnotation', + 'LocationInfo', + 'OperationMetadata', + 'OutputConfig', + 'Property', + 'SafeSearchAnnotation', + 'TextDetectionParams', + 'WebDetectionParams', + 'Likelihood', + 'ProductSearchParams', + 'ProductSearchResults', + 'AddProductToProductSetRequest', + 'BatchOperationMetadata', + 'CreateProductRequest', + 'CreateProductSetRequest', + 'CreateReferenceImageRequest', + 'DeleteProductRequest', + 'DeleteProductSetRequest', + 'DeleteReferenceImageRequest', + 'GetProductRequest', + 'GetProductSetRequest', + 'GetReferenceImageRequest', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ListProductsRequest', + 'ListProductsResponse', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'Product', + 'ProductSet', + 'ProductSetPurgeConfig', + 'PurgeProductsRequest', + 'ReferenceImage', + 'RemoveProductFromProductSetRequest', + 'UpdateProductRequest', + 'UpdateProductSetRequest', + 'Block', + 'Page', + 'Paragraph', + 'Symbol', + 'TextAnnotation', + 'Word', + 'WebDetection', +) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/face.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/face.py new file mode 100644 index 00000000..89de60a9 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/face.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p4beta1', + manifest={ + 'FaceRecognitionParams', + 'Celebrity', + 'FaceRecognitionResult', + }, +) + + +class FaceRecognitionParams(proto.Message): + r"""Parameters for a celebrity recognition request. + + Attributes: + celebrity_set (MutableSequence[str]): + The resource names for one or more + [CelebritySet][google.cloud.vision.v1p4beta1.CelebritySet]s. + A celebrity set is preloaded and can be specified as + "builtin/default". If this is specified, the algorithm will + try to match the faces detected in the input image to the + Celebrities in the CelebritySets. + """ + + celebrity_set: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + +class Celebrity(proto.Message): + r"""A Celebrity is a group of Faces with an identity. + + Attributes: + name (str): + The resource name of the preloaded Celebrity. Has the format + ``builtin/{mid}``. + display_name (str): + The Celebrity's display name. + description (str): + The Celebrity's description. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + + +class FaceRecognitionResult(proto.Message): + r"""Information about a face's identity. + + Attributes: + celebrity (google.cloud.vision_v1p4beta1.types.Celebrity): + The [Celebrity][google.cloud.vision.v1p4beta1.Celebrity] + that this face was matched to. + confidence (float): + Recognition confidence. Range [0, 1]. + """ + + celebrity: 'Celebrity' = proto.Field( + proto.MESSAGE, + number=1, + message='Celebrity', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/geometry.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/geometry.py new file mode 100644 index 00000000..a0d153de --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/geometry.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p4beta1', + manifest={ + 'Vertex', + 'NormalizedVertex', + 'BoundingPoly', + 'Position', + }, +) + + +class Vertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the vertex coordinates are in the same scale as the + original image. + + Attributes: + x (int): + X coordinate. + y (int): + Y coordinate. + """ + + x: int = proto.Field( + proto.INT32, + number=1, + ) + y: int = proto.Field( + proto.INT32, + number=2, + ) + + +class NormalizedVertex(proto.Message): + r"""A vertex represents a 2D point in the image. + NOTE: the normalized vertex coordinates are relative to the + original image and range from 0 to 1. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + + +class BoundingPoly(proto.Message): + r"""A bounding polygon for the detected image annotation. + + Attributes: + vertices (MutableSequence[google.cloud.vision_v1p4beta1.types.Vertex]): + The bounding polygon vertices. + normalized_vertices (MutableSequence[google.cloud.vision_v1p4beta1.types.NormalizedVertex]): + The bounding polygon normalized vertices. + """ + + vertices: MutableSequence['Vertex'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Vertex', + ) + normalized_vertices: MutableSequence['NormalizedVertex'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='NormalizedVertex', + ) + + +class Position(proto.Message): + r"""A 3D position in the image, used primarily for Face detection + landmarks. A valid Position must have both x and y coordinates. + The position coordinates are in the same scale as the original + image. + + Attributes: + x (float): + X coordinate. + y (float): + Y coordinate. + z (float): + Z coordinate (or depth). + """ + + x: float = proto.Field( + proto.FLOAT, + number=1, + ) + y: float = proto.Field( + proto.FLOAT, + number=2, + ) + z: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/image_annotator.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/image_annotator.py new file mode 100644 index 00000000..8c2870bf --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/image_annotator.py @@ -0,0 +1,1669 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p4beta1.types import face +from google.cloud.vision_v1p4beta1.types import geometry +from google.cloud.vision_v1p4beta1.types import product_search +from google.cloud.vision_v1p4beta1.types import text_annotation +from google.cloud.vision_v1p4beta1.types import web_detection as gcv_web_detection +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import latlng_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p4beta1', + manifest={ + 'Likelihood', + 'Feature', + 'ImageSource', + 'Image', + 'FaceAnnotation', + 'LocationInfo', + 'Property', + 'EntityAnnotation', + 'LocalizedObjectAnnotation', + 'SafeSearchAnnotation', + 'LatLongRect', + 'ColorInfo', + 'DominantColorsAnnotation', + 'ImageProperties', + 'CropHint', + 'CropHintsAnnotation', + 'CropHintsParams', + 'WebDetectionParams', + 'TextDetectionParams', + 'ImageContext', + 'AnnotateImageRequest', + 'ImageAnnotationContext', + 'AnnotateImageResponse', + 'BatchAnnotateImagesRequest', + 'BatchAnnotateImagesResponse', + 'AnnotateFileRequest', + 'AnnotateFileResponse', + 'BatchAnnotateFilesRequest', + 'BatchAnnotateFilesResponse', + 'AsyncAnnotateFileRequest', + 'AsyncAnnotateFileResponse', + 'AsyncBatchAnnotateImagesRequest', + 'AsyncBatchAnnotateImagesResponse', + 'AsyncBatchAnnotateFilesRequest', + 'AsyncBatchAnnotateFilesResponse', + 'InputConfig', + 'OutputConfig', + 'GcsSource', + 'GcsDestination', + 'OperationMetadata', + }, +) + + +class Likelihood(proto.Enum): + r"""A bucketized representation of likelihood, which is intended + to give clients highly stable results across model upgrades. + + Values: + UNKNOWN (0): + Unknown likelihood. + VERY_UNLIKELY (1): + It is very unlikely. + UNLIKELY (2): + It is unlikely. + POSSIBLE (3): + It is possible. + LIKELY (4): + It is likely. + VERY_LIKELY (5): + It is very likely. + """ + UNKNOWN = 0 + VERY_UNLIKELY = 1 + UNLIKELY = 2 + POSSIBLE = 3 + LIKELY = 4 + VERY_LIKELY = 5 + + +class Feature(proto.Message): + r"""The type of Google Cloud Vision API detection to perform, and the + maximum number of results to return for that type. Multiple + ``Feature`` objects can be specified in the ``features`` list. + + Attributes: + type_ (google.cloud.vision_v1p4beta1.types.Feature.Type): + The feature type. + max_results (int): + Maximum number of results of this type. Does not apply to + ``TEXT_DETECTION``, ``DOCUMENT_TEXT_DETECTION``, or + ``CROP_HINTS``. + model (str): + Model to use for the feature. Supported values: + "builtin/stable" (the default if unset) and + "builtin/latest". ``DOCUMENT_TEXT_DETECTION`` and + ``TEXT_DETECTION`` also support "builtin/weekly" for the + bleeding edge release updated weekly. + """ + class Type(proto.Enum): + r"""Type of Google Cloud Vision API feature to be extracted. + + Values: + TYPE_UNSPECIFIED (0): + Unspecified feature type. + FACE_DETECTION (1): + Run face detection. + LANDMARK_DETECTION (2): + Run landmark detection. + LOGO_DETECTION (3): + Run logo detection. + LABEL_DETECTION (4): + Run label detection. + TEXT_DETECTION (5): + Run text detection / optical character recognition (OCR). + Text detection is optimized for areas of text within a + larger image; if the image is a document, use + ``DOCUMENT_TEXT_DETECTION`` instead. + DOCUMENT_TEXT_DETECTION (11): + Run dense text document OCR. Takes precedence when both + ``DOCUMENT_TEXT_DETECTION`` and ``TEXT_DETECTION`` are + present. + SAFE_SEARCH_DETECTION (6): + Run Safe Search to detect potentially unsafe + or undesirable content. + IMAGE_PROPERTIES (7): + Compute a set of image properties, such as + the image's dominant colors. + CROP_HINTS (9): + Run crop hints. + WEB_DETECTION (10): + Run web detection. + PRODUCT_SEARCH (12): + Run Product Search. + OBJECT_LOCALIZATION (19): + Run localizer for object detection. + """ + TYPE_UNSPECIFIED = 0 + FACE_DETECTION = 1 + LANDMARK_DETECTION = 2 + LOGO_DETECTION = 3 + LABEL_DETECTION = 4 + TEXT_DETECTION = 5 + DOCUMENT_TEXT_DETECTION = 11 + SAFE_SEARCH_DETECTION = 6 + IMAGE_PROPERTIES = 7 + CROP_HINTS = 9 + WEB_DETECTION = 10 + PRODUCT_SEARCH = 12 + OBJECT_LOCALIZATION = 19 + + type_: Type = proto.Field( + proto.ENUM, + number=1, + enum=Type, + ) + max_results: int = proto.Field( + proto.INT32, + number=2, + ) + model: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ImageSource(proto.Message): + r"""External image source (Google Cloud Storage or web URL image + location). + + Attributes: + gcs_image_uri (str): + **Use ``image_uri`` instead.** + + The Google Cloud Storage URI of the form + ``gs://bucket_name/object_name``. Object versioning is not + supported. See `Google Cloud Storage Request + URIs `__ + for more info. + image_uri (str): + The URI of the source image. Can be either: + + 1. A Google Cloud Storage URI of the form + ``gs://bucket_name/object_name``. Object versioning is + not supported. See `Google Cloud Storage Request + URIs `__ + for more info. + + 2. A publicly-accessible image HTTP/HTTPS URL. When fetching + images from HTTP/HTTPS URLs, Google cannot guarantee that + the request will be completed. Your request may fail if + the specified host denies the request (e.g. due to + request throttling or DOS prevention), or if Google + throttles requests to the site for abuse prevention. You + should not depend on externally-hosted images for + production applications. + + When both ``gcs_image_uri`` and ``image_uri`` are specified, + ``image_uri`` takes precedence. + """ + + gcs_image_uri: str = proto.Field( + proto.STRING, + number=1, + ) + image_uri: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Image(proto.Message): + r"""Client image to perform Google Cloud Vision API tasks over. + + Attributes: + content (bytes): + Image content, represented as a stream of bytes. Note: As + with all ``bytes`` fields, protobuffers use a pure binary + representation, whereas JSON representations use base64. + source (google.cloud.vision_v1p4beta1.types.ImageSource): + Google Cloud Storage image location, or publicly-accessible + image URL. If both ``content`` and ``source`` are provided + for an image, ``content`` takes precedence and is used to + perform the image annotation request. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + source: 'ImageSource' = proto.Field( + proto.MESSAGE, + number=2, + message='ImageSource', + ) + + +class FaceAnnotation(proto.Message): + r"""A face annotation object contains the results of face + detection. + + Attributes: + bounding_poly (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The bounding polygon around the face. The coordinates of the + bounding box are in the original image's scale. The bounding + box is computed to "frame" the face in accordance with human + expectations. It is based on the landmarker results. Note + that one or more x and/or y coordinates may not be generated + in the ``BoundingPoly`` (the polygon will be unbounded) if + only a partial face appears in the image to be annotated. + fd_bounding_poly (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The ``fd_bounding_poly`` bounding polygon is tighter than + the ``boundingPoly``, and encloses only the skin part of the + face. Typically, it is used to eliminate the face from any + image analysis that detects the "amount of skin" visible in + an image. It is not based on the landmarker results, only on + the initial face detection, hence the fd (face detection) + prefix. + landmarks (MutableSequence[google.cloud.vision_v1p4beta1.types.FaceAnnotation.Landmark]): + Detected face landmarks. + roll_angle (float): + Roll angle, which indicates the amount of + clockwise/anti-clockwise rotation of the face relative to + the image vertical about the axis perpendicular to the face. + Range [-180,180]. + pan_angle (float): + Yaw angle, which indicates the leftward/rightward angle that + the face is pointing relative to the vertical plane + perpendicular to the image. Range [-180,180]. + tilt_angle (float): + Pitch angle, which indicates the upwards/downwards angle + that the face is pointing relative to the image's horizontal + plane. Range [-180,180]. + detection_confidence (float): + Detection confidence. Range [0, 1]. + landmarking_confidence (float): + Face landmarking confidence. Range [0, 1]. + joy_likelihood (google.cloud.vision_v1p4beta1.types.Likelihood): + Joy likelihood. + sorrow_likelihood (google.cloud.vision_v1p4beta1.types.Likelihood): + Sorrow likelihood. + anger_likelihood (google.cloud.vision_v1p4beta1.types.Likelihood): + Anger likelihood. + surprise_likelihood (google.cloud.vision_v1p4beta1.types.Likelihood): + Surprise likelihood. + under_exposed_likelihood (google.cloud.vision_v1p4beta1.types.Likelihood): + Under-exposed likelihood. + blurred_likelihood (google.cloud.vision_v1p4beta1.types.Likelihood): + Blurred likelihood. + headwear_likelihood (google.cloud.vision_v1p4beta1.types.Likelihood): + Headwear likelihood. + recognition_result (MutableSequence[google.cloud.vision_v1p4beta1.types.FaceRecognitionResult]): + Additional recognition information. Only computed if + image_context.face_recognition_params is provided, **and** a + match is found to a + [Celebrity][google.cloud.vision.v1p4beta1.Celebrity] in the + input + [CelebritySet][google.cloud.vision.v1p4beta1.CelebritySet]. + This field is sorted in order of decreasing confidence + values. + """ + + class Landmark(proto.Message): + r"""A face-specific landmark (for example, a face feature). + + Attributes: + type_ (google.cloud.vision_v1p4beta1.types.FaceAnnotation.Landmark.Type): + Face landmark type. + position (google.cloud.vision_v1p4beta1.types.Position): + Face landmark position. + """ + class Type(proto.Enum): + r"""Face landmark (feature) type. Left and right are defined from the + vantage of the viewer of the image without considering mirror + projections typical of photos. So, ``LEFT_EYE``, typically, is the + person's right eye. + + Values: + UNKNOWN_LANDMARK (0): + Unknown face landmark detected. Should not be + filled. + LEFT_EYE (1): + Left eye. + RIGHT_EYE (2): + Right eye. + LEFT_OF_LEFT_EYEBROW (3): + Left of left eyebrow. + RIGHT_OF_LEFT_EYEBROW (4): + Right of left eyebrow. + LEFT_OF_RIGHT_EYEBROW (5): + Left of right eyebrow. + RIGHT_OF_RIGHT_EYEBROW (6): + Right of right eyebrow. + MIDPOINT_BETWEEN_EYES (7): + Midpoint between eyes. + NOSE_TIP (8): + Nose tip. + UPPER_LIP (9): + Upper lip. + LOWER_LIP (10): + Lower lip. + MOUTH_LEFT (11): + Mouth left. + MOUTH_RIGHT (12): + Mouth right. + MOUTH_CENTER (13): + Mouth center. + NOSE_BOTTOM_RIGHT (14): + Nose, bottom right. + NOSE_BOTTOM_LEFT (15): + Nose, bottom left. + NOSE_BOTTOM_CENTER (16): + Nose, bottom center. + LEFT_EYE_TOP_BOUNDARY (17): + Left eye, top boundary. + LEFT_EYE_RIGHT_CORNER (18): + Left eye, right corner. + LEFT_EYE_BOTTOM_BOUNDARY (19): + Left eye, bottom boundary. + LEFT_EYE_LEFT_CORNER (20): + Left eye, left corner. + RIGHT_EYE_TOP_BOUNDARY (21): + Right eye, top boundary. + RIGHT_EYE_RIGHT_CORNER (22): + Right eye, right corner. + RIGHT_EYE_BOTTOM_BOUNDARY (23): + Right eye, bottom boundary. + RIGHT_EYE_LEFT_CORNER (24): + Right eye, left corner. + LEFT_EYEBROW_UPPER_MIDPOINT (25): + Left eyebrow, upper midpoint. + RIGHT_EYEBROW_UPPER_MIDPOINT (26): + Right eyebrow, upper midpoint. + LEFT_EAR_TRAGION (27): + Left ear tragion. + RIGHT_EAR_TRAGION (28): + Right ear tragion. + LEFT_EYE_PUPIL (29): + Left eye pupil. + RIGHT_EYE_PUPIL (30): + Right eye pupil. + FOREHEAD_GLABELLA (31): + Forehead glabella. + CHIN_GNATHION (32): + Chin gnathion. + CHIN_LEFT_GONION (33): + Chin left gonion. + CHIN_RIGHT_GONION (34): + Chin right gonion. + """ + UNKNOWN_LANDMARK = 0 + LEFT_EYE = 1 + RIGHT_EYE = 2 + LEFT_OF_LEFT_EYEBROW = 3 + RIGHT_OF_LEFT_EYEBROW = 4 + LEFT_OF_RIGHT_EYEBROW = 5 + RIGHT_OF_RIGHT_EYEBROW = 6 + MIDPOINT_BETWEEN_EYES = 7 + NOSE_TIP = 8 + UPPER_LIP = 9 + LOWER_LIP = 10 + MOUTH_LEFT = 11 + MOUTH_RIGHT = 12 + MOUTH_CENTER = 13 + NOSE_BOTTOM_RIGHT = 14 + NOSE_BOTTOM_LEFT = 15 + NOSE_BOTTOM_CENTER = 16 + LEFT_EYE_TOP_BOUNDARY = 17 + LEFT_EYE_RIGHT_CORNER = 18 + LEFT_EYE_BOTTOM_BOUNDARY = 19 + LEFT_EYE_LEFT_CORNER = 20 + RIGHT_EYE_TOP_BOUNDARY = 21 + RIGHT_EYE_RIGHT_CORNER = 22 + RIGHT_EYE_BOTTOM_BOUNDARY = 23 + RIGHT_EYE_LEFT_CORNER = 24 + LEFT_EYEBROW_UPPER_MIDPOINT = 25 + RIGHT_EYEBROW_UPPER_MIDPOINT = 26 + LEFT_EAR_TRAGION = 27 + RIGHT_EAR_TRAGION = 28 + LEFT_EYE_PUPIL = 29 + RIGHT_EYE_PUPIL = 30 + FOREHEAD_GLABELLA = 31 + CHIN_GNATHION = 32 + CHIN_LEFT_GONION = 33 + CHIN_RIGHT_GONION = 34 + + type_: 'FaceAnnotation.Landmark.Type' = proto.Field( + proto.ENUM, + number=3, + enum='FaceAnnotation.Landmark.Type', + ) + position: geometry.Position = proto.Field( + proto.MESSAGE, + number=4, + message=geometry.Position, + ) + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + fd_bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + landmarks: MutableSequence[Landmark] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=Landmark, + ) + roll_angle: float = proto.Field( + proto.FLOAT, + number=4, + ) + pan_angle: float = proto.Field( + proto.FLOAT, + number=5, + ) + tilt_angle: float = proto.Field( + proto.FLOAT, + number=6, + ) + detection_confidence: float = proto.Field( + proto.FLOAT, + number=7, + ) + landmarking_confidence: float = proto.Field( + proto.FLOAT, + number=8, + ) + joy_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + sorrow_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=10, + enum='Likelihood', + ) + anger_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=11, + enum='Likelihood', + ) + surprise_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=12, + enum='Likelihood', + ) + under_exposed_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=13, + enum='Likelihood', + ) + blurred_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=14, + enum='Likelihood', + ) + headwear_likelihood: 'Likelihood' = proto.Field( + proto.ENUM, + number=15, + enum='Likelihood', + ) + recognition_result: MutableSequence[face.FaceRecognitionResult] = proto.RepeatedField( + proto.MESSAGE, + number=16, + message=face.FaceRecognitionResult, + ) + + +class LocationInfo(proto.Message): + r"""Detected entity location information. + + Attributes: + lat_lng (google.type.latlng_pb2.LatLng): + lat/long location coordinates. + """ + + lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + + +class Property(proto.Message): + r"""A ``Property`` consists of a user-supplied name/value pair. + + Attributes: + name (str): + Name of the property. + value (str): + Value of the property. + uint64_value (int): + Value of numeric properties. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + uint64_value: int = proto.Field( + proto.UINT64, + number=3, + ) + + +class EntityAnnotation(proto.Message): + r"""Set of detected entity features. + + Attributes: + mid (str): + Opaque entity ID. Some IDs may be available in `Google + Knowledge Graph Search + API `__. + locale (str): + The language code for the locale in which the entity textual + ``description`` is expressed. + description (str): + Entity textual description, expressed in its ``locale`` + language. + score (float): + Overall score of the result. Range [0, 1]. + confidence (float): + **Deprecated. Use ``score`` instead.** The accuracy of the + entity detection in an image. For example, for an image in + which the "Eiffel Tower" entity is detected, this field + represents the confidence that there is a tower in the query + image. Range [0, 1]. + topicality (float): + The relevancy of the ICA (Image Content Annotation) label to + the image. For example, the relevancy of "tower" is likely + higher to an image containing the detected "Eiffel Tower" + than to an image containing a detected distant towering + building, even though the confidence that there is a tower + in each image may be the same. Range [0, 1]. + bounding_poly (google.cloud.vision_v1p4beta1.types.BoundingPoly): + Image region to which this entity belongs. Not produced for + ``LABEL_DETECTION`` features. + locations (MutableSequence[google.cloud.vision_v1p4beta1.types.LocationInfo]): + The location information for the detected entity. Multiple + ``LocationInfo`` elements can be present because one + location may indicate the location of the scene in the + image, and another location may indicate the location of the + place where the image was taken. Location information is + usually present for landmarks. + properties (MutableSequence[google.cloud.vision_v1p4beta1.types.Property]): + Some entities may have optional user-supplied ``Property`` + (name/value) fields, such a score or string that qualifies + the entity. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + locale: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + topicality: float = proto.Field( + proto.FLOAT, + number=6, + ) + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=7, + message=geometry.BoundingPoly, + ) + locations: MutableSequence['LocationInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message='LocationInfo', + ) + properties: MutableSequence['Property'] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message='Property', + ) + + +class LocalizedObjectAnnotation(proto.Message): + r"""Set of detected objects with bounding boxes. + + Attributes: + mid (str): + Object ID that should align with + EntityAnnotation mid. + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + name (str): + Object name, expressed in its ``language_code`` language. + score (float): + Score of the result. Range [0, 1]. + bounding_poly (google.cloud.vision_v1p4beta1.types.BoundingPoly): + Image region to which this object belongs. + This must be populated. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=5, + message=geometry.BoundingPoly, + ) + + +class SafeSearchAnnotation(proto.Message): + r"""Set of features pertaining to the image, computed by computer + vision methods over safe-search verticals (for example, adult, + spoof, medical, violence). + + Attributes: + adult (google.cloud.vision_v1p4beta1.types.Likelihood): + Represents the adult content likelihood for + the image. Adult content may contain elements + such as nudity, pornographic images or cartoons, + or sexual activities. + spoof (google.cloud.vision_v1p4beta1.types.Likelihood): + Spoof likelihood. The likelihood that an + modification was made to the image's canonical + version to make it appear funny or offensive. + medical (google.cloud.vision_v1p4beta1.types.Likelihood): + Likelihood that this is a medical image. + violence (google.cloud.vision_v1p4beta1.types.Likelihood): + Likelihood that this image contains violent + content. + racy (google.cloud.vision_v1p4beta1.types.Likelihood): + Likelihood that the request image contains + racy content. Racy content may include (but is + not limited to) skimpy or sheer clothing, + strategically covered nudity, lewd or + provocative poses, or close-ups of sensitive + body areas. + """ + + adult: 'Likelihood' = proto.Field( + proto.ENUM, + number=1, + enum='Likelihood', + ) + spoof: 'Likelihood' = proto.Field( + proto.ENUM, + number=2, + enum='Likelihood', + ) + medical: 'Likelihood' = proto.Field( + proto.ENUM, + number=3, + enum='Likelihood', + ) + violence: 'Likelihood' = proto.Field( + proto.ENUM, + number=4, + enum='Likelihood', + ) + racy: 'Likelihood' = proto.Field( + proto.ENUM, + number=9, + enum='Likelihood', + ) + + +class LatLongRect(proto.Message): + r"""Rectangle determined by min and max ``LatLng`` pairs. + + Attributes: + min_lat_lng (google.type.latlng_pb2.LatLng): + Min lat/long pair. + max_lat_lng (google.type.latlng_pb2.LatLng): + Max lat/long pair. + """ + + min_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=1, + message=latlng_pb2.LatLng, + ) + max_lat_lng: latlng_pb2.LatLng = proto.Field( + proto.MESSAGE, + number=2, + message=latlng_pb2.LatLng, + ) + + +class ColorInfo(proto.Message): + r"""Color information consists of RGB channels, score, and the + fraction of the image that the color occupies in the image. + + Attributes: + color (google.type.color_pb2.Color): + RGB components of the color. + score (float): + Image-specific score for this color. Value in range [0, 1]. + pixel_fraction (float): + The fraction of pixels the color occupies in the image. + Value in range [0, 1]. + """ + + color: color_pb2.Color = proto.Field( + proto.MESSAGE, + number=1, + message=color_pb2.Color, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + pixel_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class DominantColorsAnnotation(proto.Message): + r"""Set of dominant colors and their corresponding scores. + + Attributes: + colors (MutableSequence[google.cloud.vision_v1p4beta1.types.ColorInfo]): + RGB color values with their score and pixel + fraction. + """ + + colors: MutableSequence['ColorInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ColorInfo', + ) + + +class ImageProperties(proto.Message): + r"""Stores image properties, such as dominant colors. + + Attributes: + dominant_colors (google.cloud.vision_v1p4beta1.types.DominantColorsAnnotation): + If present, dominant colors completed + successfully. + """ + + dominant_colors: 'DominantColorsAnnotation' = proto.Field( + proto.MESSAGE, + number=1, + message='DominantColorsAnnotation', + ) + + +class CropHint(proto.Message): + r"""Single crop hint that is used to generate a new crop when + serving an image. + + Attributes: + bounding_poly (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The bounding polygon for the crop region. The + coordinates of the bounding box are in the + original image's scale. + confidence (float): + Confidence of this being a salient region. Range [0, 1]. + importance_fraction (float): + Fraction of importance of this salient region + with respect to the original image. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + importance_fraction: float = proto.Field( + proto.FLOAT, + number=3, + ) + + +class CropHintsAnnotation(proto.Message): + r"""Set of crop hints that are used to generate new crops when + serving images. + + Attributes: + crop_hints (MutableSequence[google.cloud.vision_v1p4beta1.types.CropHint]): + Crop hint results. + """ + + crop_hints: MutableSequence['CropHint'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='CropHint', + ) + + +class CropHintsParams(proto.Message): + r"""Parameters for crop hints annotation request. + + Attributes: + aspect_ratios (MutableSequence[float]): + Aspect ratios in floats, representing the + ratio of the width to the height of the image. + For example, if the desired aspect ratio is 4/3, + the corresponding float value should be 1.33333. + If not specified, the best possible crop is + returned. The number of provided aspect ratios + is limited to a maximum of 16; any aspect ratios + provided after the 16th are ignored. + """ + + aspect_ratios: MutableSequence[float] = proto.RepeatedField( + proto.FLOAT, + number=1, + ) + + +class WebDetectionParams(proto.Message): + r"""Parameters for web detection request. + + Attributes: + include_geo_results (bool): + Whether to include results derived from the + geo information in the image. + """ + + include_geo_results: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class TextDetectionParams(proto.Message): + r"""Parameters for text detections. This is used to control + TEXT_DETECTION and DOCUMENT_TEXT_DETECTION features. + + Attributes: + enable_text_detection_confidence_score (bool): + By default, Cloud Vision API only includes confidence score + for DOCUMENT_TEXT_DETECTION result. Set the flag to true to + include confidence score for TEXT_DETECTION as well. + advanced_ocr_options (MutableSequence[str]): + A list of advanced OCR options to fine-tune + OCR behavior. + """ + + enable_text_detection_confidence_score: bool = proto.Field( + proto.BOOL, + number=9, + ) + advanced_ocr_options: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + + +class ImageContext(proto.Message): + r"""Image context and/or feature-specific parameters. + + Attributes: + lat_long_rect (google.cloud.vision_v1p4beta1.types.LatLongRect): + Not used. + language_hints (MutableSequence[str]): + List of languages to use for TEXT_DETECTION. In most cases, + an empty value yields the best results since it enables + automatic language detection. For languages based on the + Latin alphabet, setting ``language_hints`` is not needed. In + rare cases, when the language of the text in the image is + known, setting a hint will help get better results (although + it will be a significant hindrance if the hint is wrong). + Text detection returns an error if one or more of the + specified languages is not one of the `supported + languages `__. + crop_hints_params (google.cloud.vision_v1p4beta1.types.CropHintsParams): + Parameters for crop hints annotation request. + face_recognition_params (google.cloud.vision_v1p4beta1.types.FaceRecognitionParams): + Parameters for face recognition. + product_search_params (google.cloud.vision_v1p4beta1.types.ProductSearchParams): + Parameters for product search. + web_detection_params (google.cloud.vision_v1p4beta1.types.WebDetectionParams): + Parameters for web detection. + text_detection_params (google.cloud.vision_v1p4beta1.types.TextDetectionParams): + Parameters for text detection and document + text detection. + """ + + lat_long_rect: 'LatLongRect' = proto.Field( + proto.MESSAGE, + number=1, + message='LatLongRect', + ) + language_hints: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + crop_hints_params: 'CropHintsParams' = proto.Field( + proto.MESSAGE, + number=4, + message='CropHintsParams', + ) + face_recognition_params: face.FaceRecognitionParams = proto.Field( + proto.MESSAGE, + number=10, + message=face.FaceRecognitionParams, + ) + product_search_params: product_search.ProductSearchParams = proto.Field( + proto.MESSAGE, + number=5, + message=product_search.ProductSearchParams, + ) + web_detection_params: 'WebDetectionParams' = proto.Field( + proto.MESSAGE, + number=6, + message='WebDetectionParams', + ) + text_detection_params: 'TextDetectionParams' = proto.Field( + proto.MESSAGE, + number=12, + message='TextDetectionParams', + ) + + +class AnnotateImageRequest(proto.Message): + r"""Request for performing Google Cloud Vision API tasks over a + user-provided image, with user-requested features, and with + context information. + + Attributes: + image (google.cloud.vision_v1p4beta1.types.Image): + The image to be processed. + features (MutableSequence[google.cloud.vision_v1p4beta1.types.Feature]): + Requested features. + image_context (google.cloud.vision_v1p4beta1.types.ImageContext): + Additional context that may accompany the + image. + """ + + image: 'Image' = proto.Field( + proto.MESSAGE, + number=1, + message='Image', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + + +class ImageAnnotationContext(proto.Message): + r"""If an image was produced from a file (e.g. a PDF), this + message gives information about the source of that image. + + Attributes: + uri (str): + The URI of the file used to produce the + image. + page_number (int): + If the file was a PDF or TIFF, this field + gives the page number within the file used to + produce the image. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + page_number: int = proto.Field( + proto.INT32, + number=2, + ) + + +class AnnotateImageResponse(proto.Message): + r"""Response to an image annotation request. + + Attributes: + face_annotations (MutableSequence[google.cloud.vision_v1p4beta1.types.FaceAnnotation]): + If present, face detection has completed + successfully. + landmark_annotations (MutableSequence[google.cloud.vision_v1p4beta1.types.EntityAnnotation]): + If present, landmark detection has completed + successfully. + logo_annotations (MutableSequence[google.cloud.vision_v1p4beta1.types.EntityAnnotation]): + If present, logo detection has completed + successfully. + label_annotations (MutableSequence[google.cloud.vision_v1p4beta1.types.EntityAnnotation]): + If present, label detection has completed + successfully. + localized_object_annotations (MutableSequence[google.cloud.vision_v1p4beta1.types.LocalizedObjectAnnotation]): + If present, localized object detection has + completed successfully. This will be sorted + descending by confidence score. + text_annotations (MutableSequence[google.cloud.vision_v1p4beta1.types.EntityAnnotation]): + If present, text (OCR) detection has + completed successfully. + full_text_annotation (google.cloud.vision_v1p4beta1.types.TextAnnotation): + If present, text (OCR) detection or document + (OCR) text detection has completed successfully. + This annotation provides the structural + hierarchy for the OCR detected text. + safe_search_annotation (google.cloud.vision_v1p4beta1.types.SafeSearchAnnotation): + If present, safe-search annotation has + completed successfully. + image_properties_annotation (google.cloud.vision_v1p4beta1.types.ImageProperties): + If present, image properties were extracted + successfully. + crop_hints_annotation (google.cloud.vision_v1p4beta1.types.CropHintsAnnotation): + If present, crop hints have completed + successfully. + web_detection (google.cloud.vision_v1p4beta1.types.WebDetection): + If present, web detection has completed + successfully. + product_search_results (google.cloud.vision_v1p4beta1.types.ProductSearchResults): + If present, product search has completed + successfully. + error (google.rpc.status_pb2.Status): + If set, represents the error message for the operation. Note + that filled-in image annotations are guaranteed to be + correct, even when ``error`` is set. + context (google.cloud.vision_v1p4beta1.types.ImageAnnotationContext): + If present, contextual information is needed + to understand where this image comes from. + """ + + face_annotations: MutableSequence['FaceAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='FaceAnnotation', + ) + landmark_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='EntityAnnotation', + ) + logo_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='EntityAnnotation', + ) + label_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='EntityAnnotation', + ) + localized_object_annotations: MutableSequence['LocalizedObjectAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=22, + message='LocalizedObjectAnnotation', + ) + text_annotations: MutableSequence['EntityAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='EntityAnnotation', + ) + full_text_annotation: text_annotation.TextAnnotation = proto.Field( + proto.MESSAGE, + number=12, + message=text_annotation.TextAnnotation, + ) + safe_search_annotation: 'SafeSearchAnnotation' = proto.Field( + proto.MESSAGE, + number=6, + message='SafeSearchAnnotation', + ) + image_properties_annotation: 'ImageProperties' = proto.Field( + proto.MESSAGE, + number=8, + message='ImageProperties', + ) + crop_hints_annotation: 'CropHintsAnnotation' = proto.Field( + proto.MESSAGE, + number=11, + message='CropHintsAnnotation', + ) + web_detection: gcv_web_detection.WebDetection = proto.Field( + proto.MESSAGE, + number=13, + message=gcv_web_detection.WebDetection, + ) + product_search_results: product_search.ProductSearchResults = proto.Field( + proto.MESSAGE, + number=14, + message=product_search.ProductSearchResults, + ) + error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=9, + message=status_pb2.Status, + ) + context: 'ImageAnnotationContext' = proto.Field( + proto.MESSAGE, + number=21, + message='ImageAnnotationContext', + ) + + +class BatchAnnotateImagesRequest(proto.Message): + r"""Multiple image annotation requests are batched into a single + service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + """ + + requests: MutableSequence['AnnotateImageRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageRequest', + ) + + +class BatchAnnotateImagesResponse(proto.Message): + r"""Response to a batch image annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageResponse]): + Individual responses to image annotation + requests within the batch. + """ + + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageResponse', + ) + + +class AnnotateFileRequest(proto.Message): + r"""A request to annotate one single file, e.g. a PDF, TIFF or + GIF file. + + Attributes: + input_config (google.cloud.vision_v1p4beta1.types.InputConfig): + Required. Information about the input file. + features (MutableSequence[google.cloud.vision_v1p4beta1.types.Feature]): + Required. Requested features. + image_context (google.cloud.vision_v1p4beta1.types.ImageContext): + Additional context that may accompany the + image(s) in the file. + pages (MutableSequence[int]): + Pages of the file to perform image + annotation. + Pages starts from 1, we assume the first page of + the file is page 1. At most 5 pages are + supported per request. Pages can be negative. + + Page 1 means the first page. + Page 2 means the second page. + Page -1 means the last page. + Page -2 means the second to the last page. + + If the file is GIF instead of PDF or TIFF, page + refers to GIF frames. + + If this field is empty, by default the service + performs image annotation for the first 5 pages + of the file. + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + pages: MutableSequence[int] = proto.RepeatedField( + proto.INT32, + number=4, + ) + + +class AnnotateFileResponse(proto.Message): + r"""Response to a single file annotation request. A file may + contain one or more images, which individually have their own + responses. + + Attributes: + input_config (google.cloud.vision_v1p4beta1.types.InputConfig): + Information about the file for which this + response is generated. + responses (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageResponse]): + Individual responses to images found within the file. This + field will be empty if the ``error`` field is set. + total_pages (int): + This field gives the total number of pages in + the file. + error (google.rpc.status_pb2.Status): + If set, represents the error message for the failed request. + The ``responses`` field will not be set in this case. + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + responses: MutableSequence['AnnotateImageResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='AnnotateImageResponse', + ) + total_pages: int = proto.Field( + proto.INT32, + number=3, + ) + error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=4, + message=status_pb2.Status, + ) + + +class BatchAnnotateFilesRequest(proto.Message): + r"""A list of requests to annotate files using the + BatchAnnotateFiles API. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateFileRequest]): + Required. The list of file annotation + requests. Right now we support only one + AnnotateFileRequest in + BatchAnnotateFilesRequest. + """ + + requests: MutableSequence['AnnotateFileRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateFileRequest', + ) + + +class BatchAnnotateFilesResponse(proto.Message): + r"""A list of file annotation responses. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateFileResponse]): + The list of file annotation responses, each + response corresponding to each + AnnotateFileRequest in + BatchAnnotateFilesRequest. + """ + + responses: MutableSequence['AnnotateFileResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateFileResponse', + ) + + +class AsyncAnnotateFileRequest(proto.Message): + r"""An offline file annotation request. + + Attributes: + input_config (google.cloud.vision_v1p4beta1.types.InputConfig): + Required. Information about the input file. + features (MutableSequence[google.cloud.vision_v1p4beta1.types.Feature]): + Required. Requested features. + image_context (google.cloud.vision_v1p4beta1.types.ImageContext): + Additional context that may accompany the + image(s) in the file. + output_config (google.cloud.vision_v1p4beta1.types.OutputConfig): + Required. The desired output location and + metadata (e.g. format). + """ + + input_config: 'InputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='InputConfig', + ) + features: MutableSequence['Feature'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Feature', + ) + image_context: 'ImageContext' = proto.Field( + proto.MESSAGE, + number=3, + message='ImageContext', + ) + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=4, + message='OutputConfig', + ) + + +class AsyncAnnotateFileResponse(proto.Message): + r"""The response for a single offline file annotation request. + + Attributes: + output_config (google.cloud.vision_v1p4beta1.types.OutputConfig): + The output location and metadata from + AsyncAnnotateFileRequest. + """ + + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='OutputConfig', + ) + + +class AsyncBatchAnnotateImagesRequest(proto.Message): + r"""Request for async image annotation for a list of images. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]): + Required. Individual image annotation + requests for this batch. + output_config (google.cloud.vision_v1p4beta1.types.OutputConfig): + Required. The desired output location and + metadata (e.g. format). + """ + + requests: MutableSequence['AnnotateImageRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AnnotateImageRequest', + ) + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='OutputConfig', + ) + + +class AsyncBatchAnnotateImagesResponse(proto.Message): + r"""Response to an async batch image annotation request. + + Attributes: + output_config (google.cloud.vision_v1p4beta1.types.OutputConfig): + The output location and metadata from + AsyncBatchAnnotateImagesRequest. + """ + + output_config: 'OutputConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='OutputConfig', + ) + + +class AsyncBatchAnnotateFilesRequest(proto.Message): + r"""Multiple async file annotation requests are batched into a + single service call. + + Attributes: + requests (MutableSequence[google.cloud.vision_v1p4beta1.types.AsyncAnnotateFileRequest]): + Required. Individual async file annotation + requests for this batch. + """ + + requests: MutableSequence['AsyncAnnotateFileRequest'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AsyncAnnotateFileRequest', + ) + + +class AsyncBatchAnnotateFilesResponse(proto.Message): + r"""Response to an async batch file annotation request. + + Attributes: + responses (MutableSequence[google.cloud.vision_v1p4beta1.types.AsyncAnnotateFileResponse]): + The list of file annotation responses, one + for each request in + AsyncBatchAnnotateFilesRequest. + """ + + responses: MutableSequence['AsyncAnnotateFileResponse'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='AsyncAnnotateFileResponse', + ) + + +class InputConfig(proto.Message): + r"""The desired input location and metadata. + + Attributes: + gcs_source (google.cloud.vision_v1p4beta1.types.GcsSource): + The Google Cloud Storage location to read the + input from. + content (bytes): + File content, represented as a stream of bytes. Note: As + with all ``bytes`` fields, protobuffers use a pure binary + representation, whereas JSON representations use base64. + + Currently, this field only works for BatchAnnotateFiles + requests. It does not work for AsyncBatchAnnotateFiles + requests. + mime_type (str): + The type of the file. Currently only + "application/pdf", "image/tiff" and "image/gif" + are supported. Wildcards are not supported. + """ + + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=1, + message='GcsSource', + ) + content: bytes = proto.Field( + proto.BYTES, + number=3, + ) + mime_type: str = proto.Field( + proto.STRING, + number=2, + ) + + +class OutputConfig(proto.Message): + r"""The desired output location and metadata. + + Attributes: + gcs_destination (google.cloud.vision_v1p4beta1.types.GcsDestination): + The Google Cloud Storage location to write + the output(s) to. + batch_size (int): + The max number of response protos to put into each output + JSON file on Google Cloud Storage. The valid range is [1, + 100]. If not specified, the default value is 20. + + For example, for one pdf file with 100 pages, 100 response + protos will be generated. If ``batch_size`` = 20, then 5 + json files each containing 20 response protos will be + written under the prefix ``gcs_destination``.\ ``uri``. + + Currently, batch_size only applies to GcsDestination, with + potential future support for other output configurations. + """ + + gcs_destination: 'GcsDestination' = proto.Field( + proto.MESSAGE, + number=1, + message='GcsDestination', + ) + batch_size: int = proto.Field( + proto.INT32, + number=2, + ) + + +class GcsSource(proto.Message): + r"""The Google Cloud Storage location where the input will be + read from. + + Attributes: + uri (str): + Google Cloud Storage URI for the input file. + This must only be a Google Cloud Storage object. + Wildcards are not currently supported. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GcsDestination(proto.Message): + r"""The Google Cloud Storage location where the output will be + written to. + + Attributes: + uri (str): + Google Cloud Storage URI prefix where the results will be + stored. Results will be in JSON format and preceded by its + corresponding input URI prefix. This field can either + represent a gcs file prefix or gcs directory. In either + case, the uri should be unique because in order to get all + of the output files, you will need to do a wildcard gcs + search on the uri prefix you provide. + + Examples: + + - File Prefix: gs://bucket-name/here/filenameprefix The + output files will be created in gs://bucket-name/here/ + and the names of the output files will begin with + "filenameprefix". + + - Directory Prefix: gs://bucket-name/some/location/ The + output files will be created in + gs://bucket-name/some/location/ and the names of the + output files could be anything because there was no + filename prefix specified. + + If multiple outputs, each response is still + AnnotateFileResponse, each of which contains some subset of + the full list of AnnotateImageResponse. Multiple outputs can + happen if, for example, the output JSON is too large and + overflows into multiple sharded files. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class OperationMetadata(proto.Message): + r"""Contains metadata for the BatchAnnotateImages operation. + + Attributes: + state (google.cloud.vision_v1p4beta1.types.OperationMetadata.State): + Current state of the batch operation. + create_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request was received. + update_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the operation result was last + updated. + """ + class State(proto.Enum): + r"""Batch operation states. + + Values: + STATE_UNSPECIFIED (0): + Invalid. + CREATED (1): + Request is received. + RUNNING (2): + Request is actively being processed. + DONE (3): + The batch processing is done. + CANCELLED (4): + The batch processing was cancelled. + """ + STATE_UNSPECIFIED = 0 + CREATED = 1 + RUNNING = 2 + DONE = 3 + CANCELLED = 4 + + state: State = proto.Field( + proto.ENUM, + number=1, + enum=State, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/product_search.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/product_search.py new file mode 100644 index 00000000..e77bf000 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/product_search.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p4beta1.types import geometry +from google.cloud.vision_v1p4beta1.types import product_search_service +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p4beta1', + manifest={ + 'ProductSearchParams', + 'ProductSearchResults', + }, +) + + +class ProductSearchParams(proto.Message): + r"""Parameters for a product search request. + + Attributes: + bounding_poly (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The bounding polygon around the area of + interest in the image. If it is not specified, + system discretion will be applied. + product_set (str): + The resource name of a + [ProductSet][google.cloud.vision.v1p4beta1.ProductSet] to be + searched for similar images. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID``. + product_categories (MutableSequence[str]): + The list of product categories to search in. + Currently, we only consider the first category, + and either "homegoods-v2", "apparel-v2", + "toys-v2", "packagedgoods-v1", or "general-v1" + should be specified. The legacy categories + "homegoods", "apparel", and "toys" are still + supported but will be deprecated. For new + products, please use "homegoods-v2", + "apparel-v2", or "toys-v2" for better product + search accuracy. It is recommended to migrate + existing products to these categories as well. + filter (str): + The filtering expression. This can be used to + restrict search results based on Product labels. + We currently support an AND of OR of key-value + expressions, where each expression within an OR + must have the same key. An '=' should be used to + connect the key and value. + + For example, "(color = red OR color = blue) AND + brand = Google" is acceptable, but "(color = red + OR brand = Google)" is not acceptable. "color: + red" is not acceptable because it uses a ':' + instead of an '='. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=9, + message=geometry.BoundingPoly, + ) + product_set: str = proto.Field( + proto.STRING, + number=6, + ) + product_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + filter: str = proto.Field( + proto.STRING, + number=8, + ) + + +class ProductSearchResults(proto.Message): + r"""Results for a product search request. + + Attributes: + index_time (google.protobuf.timestamp_pb2.Timestamp): + Timestamp of the index which provided these + results. Products added to the product set and + products removed from the product set after this + time are not reflected in the current results. + results (MutableSequence[google.cloud.vision_v1p4beta1.types.ProductSearchResults.Result]): + List of results, one for each product match. + product_grouped_results (MutableSequence[google.cloud.vision_v1p4beta1.types.ProductSearchResults.GroupedResult]): + List of results grouped by products detected + in the query image. Each entry corresponds to + one bounding polygon in the query image, and + contains the matching products specific to that + region. There may be duplicate product matches + in the union of all the per-product results. + """ + + class Result(proto.Message): + r"""Information about a product. + + Attributes: + product (google.cloud.vision_v1p4beta1.types.Product): + The Product. + score (float): + A confidence level on the match, ranging from + 0 (no confidence) to 1 (full confidence). + image (str): + The resource name of the image from the + product that is the closest match to the query. + """ + + product: product_search_service.Product = proto.Field( + proto.MESSAGE, + number=1, + message=product_search_service.Product, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + image: str = proto.Field( + proto.STRING, + number=3, + ) + + class ObjectAnnotation(proto.Message): + r"""Prediction for what the object in the bounding box is. + + Attributes: + mid (str): + Object ID that should align with + EntityAnnotation mid. + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + name (str): + Object name, expressed in its ``language_code`` language. + score (float): + Score of the result. Range [0, 1]. + """ + + mid: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + name: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + + class GroupedResult(proto.Message): + r"""Information about the products similar to a single product in + a query image. + + Attributes: + bounding_poly (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The bounding polygon around the product + detected in the query image. + results (MutableSequence[google.cloud.vision_v1p4beta1.types.ProductSearchResults.Result]): + List of results, one for each product match. + object_annotations (MutableSequence[google.cloud.vision_v1p4beta1.types.ProductSearchResults.ObjectAnnotation]): + List of generic predictions for the object in + the bounding box. + """ + + bounding_poly: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=1, + message=geometry.BoundingPoly, + ) + results: MutableSequence['ProductSearchResults.Result'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='ProductSearchResults.Result', + ) + object_annotations: MutableSequence['ProductSearchResults.ObjectAnnotation'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='ProductSearchResults.ObjectAnnotation', + ) + + index_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + results: MutableSequence[Result] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=Result, + ) + product_grouped_results: MutableSequence[GroupedResult] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=GroupedResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/product_search_service.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/product_search_service.py new file mode 100644 index 00000000..a49788de --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/product_search_service.py @@ -0,0 +1,1116 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p4beta1.types import geometry +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p4beta1', + manifest={ + 'Product', + 'ProductSet', + 'ReferenceImage', + 'CreateProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'GetProductRequest', + 'UpdateProductRequest', + 'DeleteProductRequest', + 'CreateProductSetRequest', + 'ListProductSetsRequest', + 'ListProductSetsResponse', + 'GetProductSetRequest', + 'UpdateProductSetRequest', + 'DeleteProductSetRequest', + 'CreateReferenceImageRequest', + 'ListReferenceImagesRequest', + 'ListReferenceImagesResponse', + 'GetReferenceImageRequest', + 'DeleteReferenceImageRequest', + 'AddProductToProductSetRequest', + 'RemoveProductFromProductSetRequest', + 'ListProductsInProductSetRequest', + 'ListProductsInProductSetResponse', + 'ImportProductSetsGcsSource', + 'ImportProductSetsInputConfig', + 'ImportProductSetsRequest', + 'ImportProductSetsResponse', + 'BatchOperationMetadata', + 'ProductSetPurgeConfig', + 'PurgeProductsRequest', + }, +) + + +class Product(proto.Message): + r"""A Product contains ReferenceImages. + + Attributes: + name (str): + The resource name of the product. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + + This field is ignored when creating a product. + display_name (str): + The user-provided name for this Product. Must + not be empty. Must be at most 4096 characters + long. + description (str): + User-provided metadata to be stored with this + product. Must be at most 4096 characters long. + product_category (str): + Immutable. The category for the product + identified by the reference image. This should + be either "homegoods-v2", "apparel-v2", or + "toys-v2". The legacy categories "homegoods", + "apparel", and "toys" are still supported, but + these should not be used for new products. + product_labels (MutableSequence[google.cloud.vision_v1p4beta1.types.Product.KeyValue]): + Key-value pairs that can be attached to a product. At query + time, constraints can be specified based on the + product_labels. + + Note that integer values can be provided as strings, e.g. + "1199". Only strings with integer values can match a + range-based restriction which is to be supported soon. + + Multiple values can be assigned to the same key. One product + may have up to 500 product_labels. + + Notice that the total number of distinct product_labels over + all products in one ProductSet cannot exceed 1M, otherwise + the product search pipeline will refuse to work for that + ProductSet. + """ + + class KeyValue(proto.Message): + r"""A product label represented as a key-value pair. + + Attributes: + key (str): + The key of the label attached to the product. + Cannot be empty and cannot exceed 128 bytes. + value (str): + The value of the label attached to the + product. Cannot be empty and cannot exceed 128 + bytes. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + product_category: str = proto.Field( + proto.STRING, + number=4, + ) + product_labels: MutableSequence[KeyValue] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=KeyValue, + ) + + +class ProductSet(proto.Message): + r"""A ProductSet contains Products. A ProductSet can contain a + maximum of 1 million reference images. If the limit is exceeded, + periodic indexing will fail. + + Attributes: + name (str): + The resource name of the ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID``. + + This field is ignored when creating a ProductSet. + display_name (str): + The user-provided name for this ProductSet. + Must not be empty. Must be at most 4096 + characters long. + index_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time at which this + ProductSet was last indexed. Query results will + reflect all updates before this time. If this + ProductSet has never been indexed, this + timestamp is the default value + "1970-01-01T00:00:00Z". + + This field is ignored when creating a + ProductSet. + index_error (google.rpc.status_pb2.Status): + Output only. If there was an error with + indexing the product set, the field is + populated. + + This field is ignored when creating a + ProductSet. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + index_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + index_error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=4, + message=status_pb2.Status, + ) + + +class ReferenceImage(proto.Message): + r"""A ``ReferenceImage`` represents a product image and its associated + metadata, such as bounding boxes. + + Attributes: + name (str): + The resource name of the reference image. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + + This field is ignored when creating a reference image. + uri (str): + Required. The Google Cloud Storage URI of the reference + image. + + The URI must start with ``gs://``. + bounding_polys (MutableSequence[google.cloud.vision_v1p4beta1.types.BoundingPoly]): + Optional. Bounding polygons around the areas + of interest in the reference image. If this + field is empty, the system will try to detect + regions of interest. At most 10 bounding + polygons will be used. + + The provided shape is converted into a + non-rotated rectangle. Once converted, the small + edge of the rectangle must be greater than or + equal to 300 pixels. The aspect ratio must be + 1:4 or less (i.e. 1:3 is ok; 1:5 is not). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + uri: str = proto.Field( + proto.STRING, + number=2, + ) + bounding_polys: MutableSequence[geometry.BoundingPoly] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=geometry.BoundingPoly, + ) + + +class CreateProductRequest(proto.Message): + r"""Request message for the ``CreateProduct`` method. + + Attributes: + parent (str): + Required. The project in which the Product should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + product (google.cloud.vision_v1p4beta1.types.Product): + Required. The product to create. + product_id (str): + A user-supplied resource id for this Product. If set, the + server will attempt to use this value as the resource id. If + it is already in use, an error is returned with code + ALREADY_EXISTS. Must be at most 128 characters long. It + cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product: 'Product' = proto.Field( + proto.MESSAGE, + number=2, + message='Product', + ) + product_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsRequest(proto.Message): + r"""Request message for the ``ListProducts`` method. + + Attributes: + parent (str): + Required. The project OR ProductSet from which Products + should be listed. + + Format: ``projects/PROJECT_ID/locations/LOC_ID`` + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsResponse(proto.Message): + r"""Response message for the ``ListProducts`` method. + + Attributes: + products (MutableSequence[google.cloud.vision_v1p4beta1.types.Product]): + List of products. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Product', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetProductRequest(proto.Message): + r"""Request message for the ``GetProduct`` method. + + Attributes: + name (str): + Required. Resource name of the Product to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductRequest(proto.Message): + r"""Request message for the ``UpdateProduct`` method. + + Attributes: + product (google.cloud.vision_v1p4beta1.types.Product): + Required. The Product resource which replaces + the one on the server. product.name is + immutable. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that specifies + which fields to update. If update_mask isn't specified, all + mutable fields are to be updated. Valid mask paths include + ``product_labels``, ``display_name``, and ``description``. + """ + + product: 'Product' = proto.Field( + proto.MESSAGE, + number=1, + message='Product', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteProductRequest(proto.Message): + r"""Request message for the ``DeleteProduct`` method. + + Attributes: + name (str): + Required. Resource name of product to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateProductSetRequest(proto.Message): + r"""Request message for the ``CreateProductSet`` method. + + Attributes: + parent (str): + Required. The project in which the ProductSet should be + created. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + product_set (google.cloud.vision_v1p4beta1.types.ProductSet): + Required. The ProductSet to create. + product_set_id (str): + A user-supplied resource id for this ProductSet. If set, the + server will attempt to use this value as the resource id. If + it is already in use, an error is returned with code + ALREADY_EXISTS. Must be at most 128 characters long. It + cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product_set: 'ProductSet' = proto.Field( + proto.MESSAGE, + number=2, + message='ProductSet', + ) + product_set_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductSetsRequest(proto.Message): + r"""Request message for the ``ListProductSets`` method. + + Attributes: + parent (str): + Required. The project from which ProductSets should be + listed. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductSetsResponse(proto.Message): + r"""Response message for the ``ListProductSets`` method. + + Attributes: + product_sets (MutableSequence[google.cloud.vision_v1p4beta1.types.ProductSet]): + List of ProductSets. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + product_sets: MutableSequence['ProductSet'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ProductSet', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GetProductSetRequest(proto.Message): + r"""Request message for the ``GetProductSet`` method. + + Attributes: + name (str): + Required. Resource name of the ProductSet to get. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductSetRequest(proto.Message): + r"""Request message for the ``UpdateProductSet`` method. + + Attributes: + product_set (google.cloud.vision_v1p4beta1.types.ProductSet): + Required. The ProductSet resource which + replaces the one on the server. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The [FieldMask][google.protobuf.FieldMask] that specifies + which fields to update. If update_mask isn't specified, all + mutable fields are to be updated. Valid mask path is + ``display_name``. + """ + + product_set: 'ProductSet' = proto.Field( + proto.MESSAGE, + number=1, + message='ProductSet', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteProductSetRequest(proto.Message): + r"""Request message for the ``DeleteProductSet`` method. + + Attributes: + name (str): + Required. Resource name of the ProductSet to delete. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateReferenceImageRequest(proto.Message): + r"""Request message for the ``CreateReferenceImage`` method. + + Attributes: + parent (str): + Required. Resource name of the product in which to create + the reference image. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + reference_image (google.cloud.vision_v1p4beta1.types.ReferenceImage): + Required. The reference image to create. + If an image ID is specified, it is ignored. + reference_image_id (str): + A user-supplied resource id for the ReferenceImage to be + added. If set, the server will attempt to use this value as + the resource id. If it is already in use, an error is + returned with code ALREADY_EXISTS. Must be at most 128 + characters long. It cannot contain the character ``/``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + reference_image: 'ReferenceImage' = proto.Field( + proto.MESSAGE, + number=2, + message='ReferenceImage', + ) + reference_image_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListReferenceImagesRequest(proto.Message): + r"""Request message for the ``ListReferenceImages`` method. + + Attributes: + parent (str): + Required. Resource name of the product containing the + reference images. + + Format is + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID``. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + A token identifying a page of results to be returned. This + is the value of ``nextPageToken`` returned in a previous + reference image list request. + + Defaults to the first page if not specified. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListReferenceImagesResponse(proto.Message): + r"""Response message for the ``ListReferenceImages`` method. + + Attributes: + reference_images (MutableSequence[google.cloud.vision_v1p4beta1.types.ReferenceImage]): + The list of reference images. + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + next_page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + @property + def raw_page(self): + return self + + reference_images: MutableSequence['ReferenceImage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ReferenceImage', + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetReferenceImageRequest(proto.Message): + r"""Request message for the ``GetReferenceImage`` method. + + Attributes: + name (str): + Required. The resource name of the ReferenceImage to get. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class DeleteReferenceImageRequest(proto.Message): + r"""Request message for the ``DeleteReferenceImage`` method. + + Attributes: + name (str): + Required. The resource name of the reference image to + delete. + + Format is: + + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID/referenceImages/IMAGE_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AddProductToProductSetRequest(proto.Message): + r"""Request message for the ``AddProductToProductSet`` method. + + Attributes: + name (str): + Required. The resource name for the ProductSet to modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + product (str): + Required. The resource name for the Product to be added to + this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + product: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RemoveProductFromProductSetRequest(proto.Message): + r"""Request message for the ``RemoveProductFromProductSet`` method. + + Attributes: + name (str): + Required. The resource name for the ProductSet to modify. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + product (str): + Required. The resource name for the Product to be removed + from this ProductSet. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/products/PRODUCT_ID`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + product: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ListProductsInProductSetRequest(proto.Message): + r"""Request message for the ``ListProductsInProductSet`` method. + + Attributes: + name (str): + Required. The ProductSet resource for which to retrieve + Products. + + Format is: + ``projects/PROJECT_ID/locations/LOC_ID/productSets/PRODUCT_SET_ID`` + page_size (int): + The maximum number of items to return. + Default 10, maximum 100. + page_token (str): + The next_page_token returned from a previous List request, + if any. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListProductsInProductSetResponse(proto.Message): + r"""Response message for the ``ListProductsInProductSet`` method. + + Attributes: + products (MutableSequence[google.cloud.vision_v1p4beta1.types.Product]): + The list of Products. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Product', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ImportProductSetsGcsSource(proto.Message): + r"""The Google Cloud Storage location for a csv file which + preserves a list of ImportProductSetRequests in each line. + + Attributes: + csv_file_uri (str): + The Google Cloud Storage URI of the input csv file. + + The URI must start with ``gs://``. + + The format of the input csv file should be one image per + line. In each line, there are 8 columns. + + 1. image-uri + 2. image-id + 3. product-set-id + 4. product-id + 5. product-category + 6. product-display-name + 7. labels + 8. bounding-poly + + The ``image-uri``, ``product-set-id``, ``product-id``, and + ``product-category`` columns are required. All other columns + are optional. + + If the ``ProductSet`` or ``Product`` specified by the + ``product-set-id`` and ``product-id`` values does not exist, + then the system will create a new ``ProductSet`` or + ``Product`` for the image. In this case, the + ``product-display-name`` column refers to + [display_name][google.cloud.vision.v1p4beta1.Product.display_name], + the ``product-category`` column refers to + [product_category][google.cloud.vision.v1p4beta1.Product.product_category], + and the ``labels`` column refers to + [product_labels][google.cloud.vision.v1p4beta1.Product.product_labels]. + + The ``image-id`` column is optional but must be unique if + provided. If it is empty, the system will automatically + assign a unique id to the image. + + The ``product-display-name`` column is optional. If it is + empty, the system sets the + [display_name][google.cloud.vision.v1p4beta1.Product.display_name] + field for the product to a space (" "). You can update the + ``display_name`` later by using the API. + + If a ``Product`` with the specified ``product-id`` already + exists, then the system ignores the + ``product-display-name``, ``product-category``, and + ``labels`` columns. + + The ``labels`` column (optional) is a line containing a list + of comma-separated key-value pairs, in the following format: + + :: + + "key_1=value_1,key_2=value_2,...,key_n=value_n" + + The ``bounding-poly`` column (optional) identifies one + region of interest from the image in the same manner as + ``CreateReferenceImage``. If you do not specify the + ``bounding-poly`` column, then the system will try to detect + regions of interest automatically. + + At most one ``bounding-poly`` column is allowed per line. If + the image contains multiple regions of interest, add a line + to the CSV file that includes the same product information, + and the ``bounding-poly`` values for each region of + interest. + + The ``bounding-poly`` column must contain an even number of + comma-separated numbers, in the format + "p1_x,p1_y,p2_x,p2_y,...,pn_x,pn_y". Use non-negative + integers for absolute bounding polygons, and float values in + [0, 1] for normalized bounding polygons. + + The system will resize the image if the image resolution is + too large to process (larger than 20MP). + """ + + csv_file_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ImportProductSetsInputConfig(proto.Message): + r"""The input content for the ``ImportProductSets`` method. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_source (google.cloud.vision_v1p4beta1.types.ImportProductSetsGcsSource): + The Google Cloud Storage location for a csv + file which preserves a list of + ImportProductSetRequests in each line. + + This field is a member of `oneof`_ ``source``. + """ + + gcs_source: 'ImportProductSetsGcsSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='ImportProductSetsGcsSource', + ) + + +class ImportProductSetsRequest(proto.Message): + r"""Request message for the ``ImportProductSets`` method. + + Attributes: + parent (str): + Required. The project in which the ProductSets should be + imported. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + input_config (google.cloud.vision_v1p4beta1.types.ImportProductSetsInputConfig): + Required. The input content for the list of + requests. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'ImportProductSetsInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportProductSetsInputConfig', + ) + + +class ImportProductSetsResponse(proto.Message): + r"""Response message for the ``ImportProductSets`` method. + + This message is returned by the + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + method in the returned + [google.longrunning.Operation.response][google.longrunning.Operation.response] + field. + + Attributes: + reference_images (MutableSequence[google.cloud.vision_v1p4beta1.types.ReferenceImage]): + The list of reference_images that are imported successfully. + statuses (MutableSequence[google.rpc.status_pb2.Status]): + The rpc status for each ImportProductSet request, including + both successes and errors. + + The number of statuses here matches the number of lines in + the csv file, and statuses[i] stores the success or failure + status of processing the i-th line of the csv, starting from + line 0. + """ + + reference_images: MutableSequence['ReferenceImage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ReferenceImage', + ) + statuses: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=status_pb2.Status, + ) + + +class BatchOperationMetadata(proto.Message): + r"""Metadata for the batch operations such as the current state. + + This is included in the ``metadata`` field of the ``Operation`` + returned by the ``GetOperation`` call of the + ``google::longrunning::Operations`` service. + + Attributes: + state (google.cloud.vision_v1p4beta1.types.BatchOperationMetadata.State): + The current state of the batch operation. + submit_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request was submitted + to the server. + end_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the batch request is finished and + [google.longrunning.Operation.done][google.longrunning.Operation.done] + is set to true. + """ + class State(proto.Enum): + r"""Enumerates the possible states that the batch request can be + in. + + Values: + STATE_UNSPECIFIED (0): + Invalid. + PROCESSING (1): + Request is actively being processed. + SUCCESSFUL (2): + The request is done and at least one item has + been successfully processed. + FAILED (3): + The request is done and no item has been + successfully processed. + CANCELLED (4): + The request is done after the + longrunning.Operations.CancelOperation has been + called by the user. Any records that were + processed before the cancel command are output + as specified in the request. + """ + STATE_UNSPECIFIED = 0 + PROCESSING = 1 + SUCCESSFUL = 2 + FAILED = 3 + CANCELLED = 4 + + state: State = proto.Field( + proto.ENUM, + number=1, + enum=State, + ) + submit_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + + +class ProductSetPurgeConfig(proto.Message): + r"""Config to control which ProductSet contains the Products to + be deleted. + + Attributes: + product_set_id (str): + The ProductSet that contains the Products to delete. If a + Product is a member of product_set_id in addition to other + ProductSets, the Product will still be deleted. + """ + + product_set_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +class PurgeProductsRequest(proto.Message): + r"""Request message for the ``PurgeProducts`` method. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + product_set_purge_config (google.cloud.vision_v1p4beta1.types.ProductSetPurgeConfig): + Specify which ProductSet contains the + Products to be deleted. + + This field is a member of `oneof`_ ``target``. + delete_orphan_products (bool): + If delete_orphan_products is true, all Products that are not + in any ProductSet will be deleted. + + This field is a member of `oneof`_ ``target``. + parent (str): + Required. The project and location in which the Products + should be deleted. + + Format is ``projects/PROJECT_ID/locations/LOC_ID``. + force (bool): + The default value is false. Override this + value to true to actually perform the purge. + """ + + product_set_purge_config: 'ProductSetPurgeConfig' = proto.Field( + proto.MESSAGE, + number=2, + oneof='target', + message='ProductSetPurgeConfig', + ) + delete_orphan_products: bool = proto.Field( + proto.BOOL, + number=3, + oneof='target', + ) + parent: str = proto.Field( + proto.STRING, + number=1, + ) + force: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/text_annotation.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/text_annotation.py new file mode 100644 index 00000000..95b45d93 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/text_annotation.py @@ -0,0 +1,429 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.vision_v1p4beta1.types import geometry + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p4beta1', + manifest={ + 'TextAnnotation', + 'Page', + 'Block', + 'Paragraph', + 'Word', + 'Symbol', + }, +) + + +class TextAnnotation(proto.Message): + r"""TextAnnotation contains a structured representation of OCR extracted + text. The hierarchy of an OCR extracted text structure is like this: + TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol Each + structural component, starting from Page, may further have their own + properties. Properties describe detected languages, breaks etc.. + Please refer to the + [TextAnnotation.TextProperty][google.cloud.vision.v1p4beta1.TextAnnotation.TextProperty] + message definition below for more detail. + + Attributes: + pages (MutableSequence[google.cloud.vision_v1p4beta1.types.Page]): + List of pages detected by OCR. + text (str): + UTF-8 text detected on the pages. + """ + + class DetectedLanguage(proto.Message): + r"""Detected language for a structural component. + + Attributes: + language_code (str): + The BCP-47 language code, such as "en-US" or "sr-Latn". For + more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + confidence (float): + Confidence of detected language. Range [0, 1]. + """ + + language_code: str = proto.Field( + proto.STRING, + number=1, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class DetectedBreak(proto.Message): + r"""Detected start or end of a structural component. + + Attributes: + type_ (google.cloud.vision_v1p4beta1.types.TextAnnotation.DetectedBreak.BreakType): + Detected break type. + is_prefix (bool): + True if break prepends the element. + """ + class BreakType(proto.Enum): + r"""Enum to denote the type of break found. New line, space etc. + + Values: + UNKNOWN (0): + Unknown break label type. + SPACE (1): + Regular space. + SURE_SPACE (2): + Sure space (very wide). + EOL_SURE_SPACE (3): + Line-wrapping break. + HYPHEN (4): + End-line hyphen that is not present in text; does not + co-occur with ``SPACE``, ``LEADER_SPACE``, or + ``LINE_BREAK``. + LINE_BREAK (5): + Line break that ends a paragraph. + """ + UNKNOWN = 0 + SPACE = 1 + SURE_SPACE = 2 + EOL_SURE_SPACE = 3 + HYPHEN = 4 + LINE_BREAK = 5 + + type_: 'TextAnnotation.DetectedBreak.BreakType' = proto.Field( + proto.ENUM, + number=1, + enum='TextAnnotation.DetectedBreak.BreakType', + ) + is_prefix: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class TextProperty(proto.Message): + r"""Additional information detected on the structural component. + + Attributes: + detected_languages (MutableSequence[google.cloud.vision_v1p4beta1.types.TextAnnotation.DetectedLanguage]): + A list of detected languages together with + confidence. + detected_break (google.cloud.vision_v1p4beta1.types.TextAnnotation.DetectedBreak): + Detected start or end of a text segment. + """ + + detected_languages: MutableSequence['TextAnnotation.DetectedLanguage'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='TextAnnotation.DetectedLanguage', + ) + detected_break: 'TextAnnotation.DetectedBreak' = proto.Field( + proto.MESSAGE, + number=2, + message='TextAnnotation.DetectedBreak', + ) + + pages: MutableSequence['Page'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Page', + ) + text: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Page(proto.Message): + r"""Detected page from OCR. + + Attributes: + property (google.cloud.vision_v1p4beta1.types.TextAnnotation.TextProperty): + Additional information detected on the page. + width (int): + Page width. For PDFs the unit is points. For + images (including TIFFs) the unit is pixels. + height (int): + Page height. For PDFs the unit is points. For + images (including TIFFs) the unit is pixels. + blocks (MutableSequence[google.cloud.vision_v1p4beta1.types.Block]): + List of blocks of text, images etc on this + page. + confidence (float): + Confidence of the OCR results on the page. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + width: int = proto.Field( + proto.INT32, + number=2, + ) + height: int = proto.Field( + proto.INT32, + number=3, + ) + blocks: MutableSequence['Block'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='Block', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Block(proto.Message): + r"""Logical element on the page. + + Attributes: + property (google.cloud.vision_v1p4beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + block. + bounding_box (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The bounding box for the block. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: + + :: + + 0----1 + | | + 3----2 + + - when it's rotated 180 degrees around the top-left corner + it becomes: + + :: + + 2----3 + | | + 1----0 + + and the vertex order will still be (0, 1, 2, 3). + paragraphs (MutableSequence[google.cloud.vision_v1p4beta1.types.Paragraph]): + List of paragraphs in this block (if this + blocks is of type text). + block_type (google.cloud.vision_v1p4beta1.types.Block.BlockType): + Detected block type (text, image etc) for + this block. + confidence (float): + Confidence of the OCR results on the block. Range [0, 1]. + """ + class BlockType(proto.Enum): + r"""Type of a block (text, image etc) as identified by OCR. + + Values: + UNKNOWN (0): + Unknown block type. + TEXT (1): + Regular text block. + TABLE (2): + Table block. + PICTURE (3): + Image block. + RULER (4): + Horizontal/vertical line box. + BARCODE (5): + Barcode block. + """ + UNKNOWN = 0 + TEXT = 1 + TABLE = 2 + PICTURE = 3 + RULER = 4 + BARCODE = 5 + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + paragraphs: MutableSequence['Paragraph'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Paragraph', + ) + block_type: BlockType = proto.Field( + proto.ENUM, + number=4, + enum=BlockType, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=5, + ) + + +class Paragraph(proto.Message): + r"""Structural unit of text representing a number of words in + certain order. + + Attributes: + property (google.cloud.vision_v1p4beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + paragraph. + bounding_box (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The bounding box for the paragraph. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertex order will + still be (0, 1, 2, 3). + words (MutableSequence[google.cloud.vision_v1p4beta1.types.Word]): + List of all words in this paragraph. + confidence (float): + Confidence of the OCR results for the paragraph. Range [0, + 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + words: MutableSequence['Word'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Word', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Word(proto.Message): + r"""A word representation. + + Attributes: + property (google.cloud.vision_v1p4beta1.types.TextAnnotation.TextProperty): + Additional information detected for the word. + bounding_box (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The bounding box for the word. The vertices are in the order + of top-left, top-right, bottom-right, bottom-left. When a + rotation of the bounding box is detected the rotation is + represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertex order will + still be (0, 1, 2, 3). + symbols (MutableSequence[google.cloud.vision_v1p4beta1.types.Symbol]): + List of symbols in the word. + The order of the symbols follows the natural + reading order. + confidence (float): + Confidence of the OCR results for the word. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + symbols: MutableSequence['Symbol'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Symbol', + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +class Symbol(proto.Message): + r"""A single symbol representation. + + Attributes: + property (google.cloud.vision_v1p4beta1.types.TextAnnotation.TextProperty): + Additional information detected for the + symbol. + bounding_box (google.cloud.vision_v1p4beta1.types.BoundingPoly): + The bounding box for the symbol. The vertices are in the + order of top-left, top-right, bottom-right, bottom-left. + When a rotation of the bounding box is detected the rotation + is represented as around the top-left corner as defined when + the text is read in the 'natural' orientation. For example: + + - when the text is horizontal it might look like: 0----1 \| + \| 3----2 + - when it's rotated 180 degrees around the top-left corner + it becomes: 2----3 \| \| 1----0 and the vertex order will + still be (0, 1, 2, 3). + text (str): + The actual UTF-8 representation of the + symbol. + confidence (float): + Confidence of the OCR results for the symbol. Range [0, 1]. + """ + + property: 'TextAnnotation.TextProperty' = proto.Field( + proto.MESSAGE, + number=1, + message='TextAnnotation.TextProperty', + ) + bounding_box: geometry.BoundingPoly = proto.Field( + proto.MESSAGE, + number=2, + message=geometry.BoundingPoly, + ) + text: str = proto.Field( + proto.STRING, + number=3, + ) + confidence: float = proto.Field( + proto.FLOAT, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/web_detection.py b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/web_detection.py new file mode 100644 index 00000000..88f321f9 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/google/cloud/vision_v1p4beta1/types/web_detection.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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 typing import MutableMapping, MutableSequence + +import proto # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.vision.v1p4beta1', + manifest={ + 'WebDetection', + }, +) + + +class WebDetection(proto.Message): + r"""Relevant information for the image from the Internet. + + Attributes: + web_entities (MutableSequence[google.cloud.vision_v1p4beta1.types.WebDetection.WebEntity]): + Deduced entities from similar images on the + Internet. + full_matching_images (MutableSequence[google.cloud.vision_v1p4beta1.types.WebDetection.WebImage]): + Fully matching images from the Internet. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1p4beta1.types.WebDetection.WebImage]): + Partial matching images from the Internet. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + pages_with_matching_images (MutableSequence[google.cloud.vision_v1p4beta1.types.WebDetection.WebPage]): + Web pages containing the matching images from + the Internet. + visually_similar_images (MutableSequence[google.cloud.vision_v1p4beta1.types.WebDetection.WebImage]): + The visually similar image results. + best_guess_labels (MutableSequence[google.cloud.vision_v1p4beta1.types.WebDetection.WebLabel]): + The service's best guess as to the topic of + the request image. Inferred from similar images + on the open web. + """ + + class WebEntity(proto.Message): + r"""Entity deduced from similar images on the Internet. + + Attributes: + entity_id (str): + Opaque entity ID. + score (float): + Overall relevancy score for the entity. + Not normalized and not comparable across + different image queries. + description (str): + Canonical description of the entity, in + English. + """ + + entity_id: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + + class WebImage(proto.Message): + r"""Metadata for online images. + + Attributes: + url (str): + The result image URL. + score (float): + (Deprecated) Overall relevancy score for the + image. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + + class WebPage(proto.Message): + r"""Metadata for web pages. + + Attributes: + url (str): + The result web page URL. + score (float): + (Deprecated) Overall relevancy score for the + web page. + page_title (str): + Title for the web page, may contain HTML + markups. + full_matching_images (MutableSequence[google.cloud.vision_v1p4beta1.types.WebDetection.WebImage]): + Fully matching images on the page. + Can include resized copies of the query image. + partial_matching_images (MutableSequence[google.cloud.vision_v1p4beta1.types.WebDetection.WebImage]): + Partial matching images on the page. + Those images are similar enough to share some + key-point features. For example an original + image will likely have partial matching for its + crops. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + ) + page_title: str = proto.Field( + proto.STRING, + number=3, + ) + full_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='WebDetection.WebImage', + ) + partial_matching_images: MutableSequence['WebDetection.WebImage'] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message='WebDetection.WebImage', + ) + + class WebLabel(proto.Message): + r"""Label to provide extra metadata for the web detection. + + Attributes: + label (str): + Label for extra metadata. + language_code (str): + The BCP-47 language code for ``label``, such as "en-US" or + "sr-Latn". For more information, see + http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + """ + + label: str = proto.Field( + proto.STRING, + number=1, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + ) + + web_entities: MutableSequence[WebEntity] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=WebEntity, + ) + full_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=WebImage, + ) + partial_matching_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=WebImage, + ) + pages_with_matching_images: MutableSequence[WebPage] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=WebPage, + ) + visually_similar_images: MutableSequence[WebImage] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=WebImage, + ) + best_guess_labels: MutableSequence[WebLabel] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=WebLabel, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v1p4beta1/mypy.ini b/owl-bot-staging/v1p4beta1/mypy.ini new file mode 100644 index 00000000..574c5aed --- /dev/null +++ b/owl-bot-staging/v1p4beta1/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/v1p4beta1/noxfile.py b/owl-bot-staging/v1p4beta1/noxfile.py new file mode 100644 index 00000000..2b6730f4 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/noxfile.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +import pathlib +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = subprocess.check_output([sys.executable, "setup.py", "--name"], encoding="utf-8") + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.11" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "lint_setup_py", +] + +@nox.session(python=ALL_PYTHON) +def unit(session): + """Run the unit test suite.""" + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.') + + session.run( + 'py.test', + '--quiet', + '--cov=google/cloud/vision_v1p4beta1/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)) + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python=ALL_PYTHON) +def mypy(session): + """Run the type checker.""" + session.install( + 'mypy', + 'types-requests', + 'types-protobuf' + ) + session.install('.') + session.run( + 'mypy', + '--explicit-package-bases', + 'google', + ) + + +@nox.session +def update_lower_bounds(session): + """Update lower bounds in constraints.txt to match setup.py""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'update', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + + +@nox.session +def check_lower_bounds(session): + """Check lower bounds in setup.py are reflected in constraints file""" + session.install('google-cloud-testutils') + session.install('.') + + session.run( + 'lower-bound-checker', + 'check', + '--package-name', + PACKAGE_NAME, + '--constraints-file', + str(LOWER_BOUND_CONSTRAINTS_FILE), + ) + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install("sphinx==7.0.1", "alabaster", "recommonmark") + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install("flake8", BLACK_VERSION) + session.run( + "black", + "--check", + *BLACK_PATHS, + ) + session.run("flake8", "google", "tests", "samples") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *BLACK_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json b/owl-bot-staging/v1p4beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json new file mode 100644 index 00000000..a1201ce4 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/snippet_metadata_google.cloud.vision.v1p4beta1.json @@ -0,0 +1,3784 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.vision.v1p4beta1", + "version": "v1p4beta1" + } + ], + "language": "PYTHON", + "name": "google-cloud-vision", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorAsyncClient.async_batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator.AsyncBatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p4beta1.types.AsyncAnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "async_batch_annotate_files" + }, + "description": "Sample for AsyncBatchAnnotateFiles", + "file": "vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorClient.async_batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator.AsyncBatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p4beta1.types.AsyncAnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "async_batch_annotate_files" + }, + "description": "Sample for AsyncBatchAnnotateFiles", + "file": "vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorAsyncClient.async_batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator.AsyncBatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]" + }, + { + "name": "output_config", + "type": "google.cloud.vision_v1p4beta1.types.OutputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "async_batch_annotate_images" + }, + "description": "Sample for AsyncBatchAnnotateImages", + "file": "vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateImages_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorClient.async_batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator.AsyncBatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "AsyncBatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.AsyncBatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]" + }, + { + "name": "output_config", + "type": "google.cloud.vision_v1p4beta1.types.OutputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "async_batch_annotate_images" + }, + "description": "Sample for AsyncBatchAnnotateImages", + "file": "vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateImages_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorAsyncClient.batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator.BatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.BatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.BatchAnnotateFilesResponse", + "shortName": "batch_annotate_files" + }, + "description": "Sample for BatchAnnotateFiles", + "file": "vision_v1p4beta1_generated_image_annotator_batch_annotate_files_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateFiles_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_image_annotator_batch_annotate_files_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorClient.batch_annotate_files", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator.BatchAnnotateFiles", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateFiles" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.BatchAnnotateFilesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateFileRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.BatchAnnotateFilesResponse", + "shortName": "batch_annotate_files" + }, + "description": "Sample for BatchAnnotateFiles", + "file": "vision_v1p4beta1_generated_image_annotator_batch_annotate_files_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateFiles_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_image_annotator_batch_annotate_files_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorAsyncClient", + "shortName": "ImageAnnotatorAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorAsyncClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1p4beta1_generated_image_annotator_batch_annotate_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateImages_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_image_annotator_batch_annotate_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorClient", + "shortName": "ImageAnnotatorClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ImageAnnotatorClient.batch_annotate_images", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator.BatchAnnotateImages", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ImageAnnotator", + "shortName": "ImageAnnotator" + }, + "shortName": "BatchAnnotateImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.BatchAnnotateImagesRequest" + }, + { + "name": "requests", + "type": "MutableSequence[google.cloud.vision_v1p4beta1.types.AnnotateImageRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.BatchAnnotateImagesResponse", + "shortName": "batch_annotate_images" + }, + "description": "Sample for BatchAnnotateImages", + "file": "vision_v1p4beta1_generated_image_annotator_batch_annotate_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateImages_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_image_annotator_batch_annotate_images_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.add_product_to_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.AddProductToProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "AddProductToProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.AddProductToProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "add_product_to_product_set" + }, + "description": "Sample for AddProductToProductSet", + "file": "vision_v1p4beta1_generated_product_search_add_product_to_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_AddProductToProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_add_product_to_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.add_product_to_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.AddProductToProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "AddProductToProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.AddProductToProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "add_product_to_product_set" + }, + "description": "Sample for AddProductToProductSet", + "file": "vision_v1p4beta1_generated_product_search_add_product_to_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_AddProductToProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_add_product_to_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.create_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.CreateProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.CreateProductSetRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1p4beta1.types.ProductSet" + }, + { + "name": "product_set_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ProductSet", + "shortName": "create_product_set" + }, + "description": "Sample for CreateProductSet", + "file": "vision_v1p4beta1_generated_product_search_create_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_CreateProductSet_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_create_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.create_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.CreateProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.CreateProductSetRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1p4beta1.types.ProductSet" + }, + { + "name": "product_set_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ProductSet", + "shortName": "create_product_set" + }, + "description": "Sample for CreateProductSet", + "file": "vision_v1p4beta1_generated_product_search_create_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_CreateProductSet_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_create_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.create_product", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.CreateProduct", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.vision_v1p4beta1.types.Product" + }, + { + "name": "product_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "vision_v1p4beta1_generated_product_search_create_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_CreateProduct_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_create_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.create_product", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.CreateProduct", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.vision_v1p4beta1.types.Product" + }, + { + "name": "product_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "vision_v1p4beta1_generated_product_search_create_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_CreateProduct_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_create_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.create_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.CreateReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.CreateReferenceImageRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "reference_image", + "type": "google.cloud.vision_v1p4beta1.types.ReferenceImage" + }, + { + "name": "reference_image_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ReferenceImage", + "shortName": "create_reference_image" + }, + "description": "Sample for CreateReferenceImage", + "file": "vision_v1p4beta1_generated_product_search_create_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_CreateReferenceImage_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_create_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.create_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.CreateReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "CreateReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.CreateReferenceImageRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "reference_image", + "type": "google.cloud.vision_v1p4beta1.types.ReferenceImage" + }, + { + "name": "reference_image_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ReferenceImage", + "shortName": "create_reference_image" + }, + "description": "Sample for CreateReferenceImage", + "file": "vision_v1p4beta1_generated_product_search_create_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_CreateReferenceImage_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_create_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.delete_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.DeleteProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.DeleteProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product_set" + }, + "description": "Sample for DeleteProductSet", + "file": "vision_v1p4beta1_generated_product_search_delete_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_DeleteProductSet_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_delete_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.delete_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.DeleteProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.DeleteProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product_set" + }, + "description": "Sample for DeleteProductSet", + "file": "vision_v1p4beta1_generated_product_search_delete_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_DeleteProductSet_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_delete_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.delete_product", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.DeleteProduct", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.DeleteProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product" + }, + "description": "Sample for DeleteProduct", + "file": "vision_v1p4beta1_generated_product_search_delete_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_DeleteProduct_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_delete_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.delete_product", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.DeleteProduct", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.DeleteProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_product" + }, + "description": "Sample for DeleteProduct", + "file": "vision_v1p4beta1_generated_product_search_delete_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_DeleteProduct_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_delete_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.delete_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.DeleteReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.DeleteReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_reference_image" + }, + "description": "Sample for DeleteReferenceImage", + "file": "vision_v1p4beta1_generated_product_search_delete_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_DeleteReferenceImage_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_delete_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.delete_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.DeleteReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "DeleteReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.DeleteReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "delete_reference_image" + }, + "description": "Sample for DeleteReferenceImage", + "file": "vision_v1p4beta1_generated_product_search_delete_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_DeleteReferenceImage_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_delete_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.get_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.GetProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.GetProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ProductSet", + "shortName": "get_product_set" + }, + "description": "Sample for GetProductSet", + "file": "vision_v1p4beta1_generated_product_search_get_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_GetProductSet_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_get_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.get_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.GetProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.GetProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ProductSet", + "shortName": "get_product_set" + }, + "description": "Sample for GetProductSet", + "file": "vision_v1p4beta1_generated_product_search_get_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_GetProductSet_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_get_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.get_product", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.GetProduct", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.GetProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "vision_v1p4beta1_generated_product_search_get_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_GetProduct_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_get_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.get_product", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.GetProduct", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.GetProductRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "vision_v1p4beta1_generated_product_search_get_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_GetProduct_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_get_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.get_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.GetReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.GetReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ReferenceImage", + "shortName": "get_reference_image" + }, + "description": "Sample for GetReferenceImage", + "file": "vision_v1p4beta1_generated_product_search_get_reference_image_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_GetReferenceImage_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_get_reference_image_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.get_reference_image", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.GetReferenceImage", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "GetReferenceImage" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.GetReferenceImageRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ReferenceImage", + "shortName": "get_reference_image" + }, + "description": "Sample for GetReferenceImage", + "file": "vision_v1p4beta1_generated_product_search_get_reference_image_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_GetReferenceImage_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_get_reference_image_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.import_product_sets", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ImportProductSets", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ImportProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ImportProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "input_config", + "type": "google.cloud.vision_v1p4beta1.types.ImportProductSetsInputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "import_product_sets" + }, + "description": "Sample for ImportProductSets", + "file": "vision_v1p4beta1_generated_product_search_import_product_sets_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ImportProductSets_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_import_product_sets_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.import_product_sets", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ImportProductSets", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ImportProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ImportProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "input_config", + "type": "google.cloud.vision_v1p4beta1.types.ImportProductSetsInputConfig" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "import_product_sets" + }, + "description": "Sample for ImportProductSets", + "file": "vision_v1p4beta1_generated_product_search_import_product_sets_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ImportProductSets_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_import_product_sets_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.list_product_sets", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ListProductSets", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ListProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductSetsAsyncPager", + "shortName": "list_product_sets" + }, + "description": "Sample for ListProductSets", + "file": "vision_v1p4beta1_generated_product_search_list_product_sets_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ListProductSets_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_list_product_sets_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.list_product_sets", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ListProductSets", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductSets" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ListProductSetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductSetsPager", + "shortName": "list_product_sets" + }, + "description": "Sample for ListProductSets", + "file": "vision_v1p4beta1_generated_product_search_list_product_sets_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ListProductSets_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_list_product_sets_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.list_products_in_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ListProductsInProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductsInProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ListProductsInProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductsInProductSetAsyncPager", + "shortName": "list_products_in_product_set" + }, + "description": "Sample for ListProductsInProductSet", + "file": "vision_v1p4beta1_generated_product_search_list_products_in_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ListProductsInProductSet_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_list_products_in_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.list_products_in_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ListProductsInProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProductsInProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ListProductsInProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductsInProductSetPager", + "shortName": "list_products_in_product_set" + }, + "description": "Sample for ListProductsInProductSet", + "file": "vision_v1p4beta1_generated_product_search_list_products_in_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ListProductsInProductSet_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_list_products_in_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.list_products", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ListProducts", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ListProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductsAsyncPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "vision_v1p4beta1_generated_product_search_list_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ListProducts_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_list_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.list_products", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ListProducts", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ListProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.services.product_search.pagers.ListProductsPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "vision_v1p4beta1_generated_product_search_list_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ListProducts_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_list_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.list_reference_images", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ListReferenceImages", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListReferenceImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ListReferenceImagesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.services.product_search.pagers.ListReferenceImagesAsyncPager", + "shortName": "list_reference_images" + }, + "description": "Sample for ListReferenceImages", + "file": "vision_v1p4beta1_generated_product_search_list_reference_images_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ListReferenceImages_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_list_reference_images_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.list_reference_images", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.ListReferenceImages", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "ListReferenceImages" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.ListReferenceImagesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.services.product_search.pagers.ListReferenceImagesPager", + "shortName": "list_reference_images" + }, + "description": "Sample for ListReferenceImages", + "file": "vision_v1p4beta1_generated_product_search_list_reference_images_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_ListReferenceImages_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_list_reference_images_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.purge_products", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.PurgeProducts", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "PurgeProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.PurgeProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "purge_products" + }, + "description": "Sample for PurgeProducts", + "file": "vision_v1p4beta1_generated_product_search_purge_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_PurgeProducts_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_purge_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.purge_products", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.PurgeProducts", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "PurgeProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.PurgeProductsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "purge_products" + }, + "description": "Sample for PurgeProducts", + "file": "vision_v1p4beta1_generated_product_search_purge_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_PurgeProducts_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_purge_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.remove_product_from_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.RemoveProductFromProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "RemoveProductFromProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.RemoveProductFromProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "remove_product_from_product_set" + }, + "description": "Sample for RemoveProductFromProductSet", + "file": "vision_v1p4beta1_generated_product_search_remove_product_from_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_RemoveProductFromProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_remove_product_from_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.remove_product_from_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.RemoveProductFromProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "RemoveProductFromProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.RemoveProductFromProductSetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "remove_product_from_product_set" + }, + "description": "Sample for RemoveProductFromProductSet", + "file": "vision_v1p4beta1_generated_product_search_remove_product_from_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_RemoveProductFromProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_remove_product_from_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.update_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.UpdateProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.UpdateProductSetRequest" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1p4beta1.types.ProductSet" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ProductSet", + "shortName": "update_product_set" + }, + "description": "Sample for UpdateProductSet", + "file": "vision_v1p4beta1_generated_product_search_update_product_set_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_UpdateProductSet_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_update_product_set_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.update_product_set", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.UpdateProductSet", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProductSet" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.UpdateProductSetRequest" + }, + { + "name": "product_set", + "type": "google.cloud.vision_v1p4beta1.types.ProductSet" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.ProductSet", + "shortName": "update_product_set" + }, + "description": "Sample for UpdateProductSet", + "file": "vision_v1p4beta1_generated_product_search_update_product_set_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_UpdateProductSet_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_update_product_set_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient", + "shortName": "ProductSearchAsyncClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchAsyncClient.update_product", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.UpdateProduct", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.vision_v1p4beta1.types.Product" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "vision_v1p4beta1_generated_product_search_update_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_UpdateProduct_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_update_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient", + "shortName": "ProductSearchClient" + }, + "fullName": "google.cloud.vision_v1p4beta1.ProductSearchClient.update_product", + "method": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch.UpdateProduct", + "service": { + "fullName": "google.cloud.vision.v1p4beta1.ProductSearch", + "shortName": "ProductSearch" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.vision_v1p4beta1.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.vision_v1p4beta1.types.Product" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.vision_v1p4beta1.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "vision_v1p4beta1_generated_product_search_update_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "vision_v1p4beta1_generated_ProductSearch_UpdateProduct_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "vision_v1p4beta1_generated_product_search_update_product_sync.py" + } + ] +} diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_async.py new file mode 100644 index 00000000..c375e0fe --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_sync.py new file mode 100644 index 00000000..b9319936 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_files_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_async_batch_annotate_files(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AsyncBatchAnnotateFilesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_files(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateFiles_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_async.py new file mode 100644 index 00000000..bc9b918b --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_async.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_async_batch_annotate_images(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AsyncBatchAnnotateImagesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_images(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateImages_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_sync.py new file mode 100644 index 00000000..ea446343 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_async_batch_annotate_images_sync.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AsyncBatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_async_batch_annotate_images(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AsyncBatchAnnotateImagesRequest( + ) + + # Make the request + operation = client.async_batch_annotate_images(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ImageAnnotator_AsyncBatchAnnotateImages_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_files_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_files_async.py new file mode 100644 index 00000000..19d68278 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_files_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateFiles_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_batch_annotate_files(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.BatchAnnotateFilesRequest( + ) + + # Make the request + response = await client.batch_annotate_files(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateFiles_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_files_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_files_sync.py new file mode 100644 index 00000000..547b26f1 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_files_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateFiles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateFiles_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_batch_annotate_files(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.BatchAnnotateFilesRequest( + ) + + # Make the request + response = client.batch_annotate_files(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateFiles_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_images_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_images_async.py new file mode 100644 index 00000000..69866345 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_images_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_batch_annotate_images(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = await client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateImages_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_images_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_images_sync.py new file mode 100644 index 00000000..108be86c --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_image_annotator_batch_annotate_images_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAnnotateImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_batch_annotate_images(): + # Create a client + client = vision_v1p4beta1.ImageAnnotatorClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.BatchAnnotateImagesRequest( + ) + + # Make the request + response = client.batch_annotate_images(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ImageAnnotator_BatchAnnotateImages_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_add_product_to_product_set_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_add_product_to_product_set_async.py new file mode 100644 index 00000000..596b6415 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_add_product_to_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AddProductToProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_AddProductToProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_add_product_to_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.add_product_to_product_set(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_AddProductToProductSet_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_add_product_to_product_set_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_add_product_to_product_set_sync.py new file mode 100644 index 00000000..b03282bb --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_add_product_to_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for AddProductToProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_AddProductToProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_add_product_to_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.AddProductToProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.add_product_to_product_set(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_AddProductToProductSet_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_async.py new file mode 100644 index 00000000..ce8cfa9d --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_CreateProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_create_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_CreateProduct_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_set_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_set_async.py new file mode 100644 index 00000000..8b654064 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_set_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_CreateProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_create_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_CreateProductSet_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_set_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_set_sync.py new file mode 100644 index 00000000..010f82fe --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_set_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_CreateProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_create_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.CreateProductSetRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_CreateProductSet_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_sync.py new file mode 100644 index 00000000..eaf163ba --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_product_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_CreateProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_create_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.CreateProductRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_CreateProduct_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_reference_image_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_reference_image_async.py new file mode 100644 index 00000000..e61f71d6 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_reference_image_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_CreateReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_create_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + reference_image = vision_v1p4beta1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1p4beta1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = await client.create_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_CreateReferenceImage_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_reference_image_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_reference_image_sync.py new file mode 100644 index 00000000..8d7ce186 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_create_reference_image_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_CreateReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_create_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + reference_image = vision_v1p4beta1.ReferenceImage() + reference_image.uri = "uri_value" + + request = vision_v1p4beta1.CreateReferenceImageRequest( + parent="parent_value", + reference_image=reference_image, + ) + + # Make the request + response = client.create_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_CreateReferenceImage_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_async.py new file mode 100644 index 00000000..466672f4 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_DeleteProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_delete_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_DeleteProduct_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_set_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_set_async.py new file mode 100644 index 00000000..75c7bf29 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_set_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_DeleteProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_delete_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + await client.delete_product_set(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_DeleteProductSet_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_set_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_set_sync.py new file mode 100644 index 00000000..aebd4988 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_set_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_DeleteProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_delete_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteProductSetRequest( + name="name_value", + ) + + # Make the request + client.delete_product_set(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_DeleteProductSet_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_sync.py new file mode 100644 index 00000000..c121ef37 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_product_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_DeleteProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_delete_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_DeleteProduct_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_reference_image_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_reference_image_async.py new file mode 100644 index 00000000..543514be --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_reference_image_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_DeleteReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_delete_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + await client.delete_reference_image(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_DeleteReferenceImage_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_reference_image_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_reference_image_sync.py new file mode 100644 index 00000000..8d0f6b5d --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_delete_reference_image_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_DeleteReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_delete_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.DeleteReferenceImageRequest( + name="name_value", + ) + + # Make the request + client.delete_reference_image(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_DeleteReferenceImage_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_async.py new file mode 100644 index 00000000..0cfe0582 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_GetProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_get_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_GetProduct_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_set_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_set_async.py new file mode 100644 index 00000000..7904b9a0 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_set_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_GetProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_get_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_GetProductSet_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_set_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_set_sync.py new file mode 100644 index 00000000..2436b58a --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_set_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_GetProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_get_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetProductSetRequest( + name="name_value", + ) + + # Make the request + response = client.get_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_GetProductSet_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_sync.py new file mode 100644 index 00000000..945c78f9 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_product_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_GetProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_get_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_GetProduct_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_reference_image_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_reference_image_async.py new file mode 100644 index 00000000..02cba60c --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_reference_image_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_GetReferenceImage_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_get_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = await client.get_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_GetReferenceImage_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_reference_image_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_reference_image_sync.py new file mode 100644 index 00000000..a2f39083 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_get_reference_image_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetReferenceImage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_GetReferenceImage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_get_reference_image(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.GetReferenceImageRequest( + name="name_value", + ) + + # Make the request + response = client.get_reference_image(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_GetReferenceImage_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_import_product_sets_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_import_product_sets_async.py new file mode 100644 index 00000000..251702c9 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_import_product_sets_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ImportProductSets_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_import_product_sets(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ImportProductSets_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_import_product_sets_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_import_product_sets_sync.py new file mode 100644 index 00000000..bb656169 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_import_product_sets_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ImportProductSets_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_import_product_sets(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ImportProductSetsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.import_product_sets(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ImportProductSets_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_product_sets_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_product_sets_async.py new file mode 100644 index 00000000..79052743 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_product_sets_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ListProductSets_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_list_product_sets(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ListProductSets_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_product_sets_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_product_sets_sync.py new file mode 100644 index 00000000..048d00ef --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_product_sets_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductSets +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ListProductSets_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_list_product_sets(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductSetsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_product_sets(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ListProductSets_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_async.py new file mode 100644 index 00000000..91fcd1cc --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ListProducts_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_list_products(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ListProducts_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_in_product_set_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_in_product_set_async.py new file mode 100644 index 00000000..d3c5ba33 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_in_product_set_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductsInProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ListProductsInProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_list_products_in_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ListProductsInProductSet_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_in_product_set_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_in_product_set_sync.py new file mode 100644 index 00000000..1009061f --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_in_product_set_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProductsInProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ListProductsInProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_list_products_in_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductsInProductSetRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_products_in_product_set(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ListProductsInProductSet_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_sync.py new file mode 100644 index 00000000..943f9bf3 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_products_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ListProducts_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_list_products(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListProductsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_products(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ListProducts_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_reference_images_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_reference_images_async.py new file mode 100644 index 00000000..e9a8f806 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_reference_images_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListReferenceImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ListReferenceImages_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_list_reference_images(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ListReferenceImages_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_reference_images_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_reference_images_sync.py new file mode 100644 index 00000000..a5c836ef --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_list_reference_images_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListReferenceImages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_ListReferenceImages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_list_reference_images(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.ListReferenceImagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_reference_images(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_ListReferenceImages_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_purge_products_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_purge_products_async.py new file mode 100644 index 00000000..3ec9b56a --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_purge_products_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for PurgeProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_PurgeProducts_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_purge_products(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.PurgeProductsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.purge_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_PurgeProducts_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_purge_products_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_purge_products_sync.py new file mode 100644 index 00000000..6a3ad5e4 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_purge_products_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for PurgeProducts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_PurgeProducts_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_purge_products(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.PurgeProductsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.purge_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_PurgeProducts_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_remove_product_from_product_set_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_remove_product_from_product_set_async.py new file mode 100644 index 00000000..9f5ea9fe --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_remove_product_from_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RemoveProductFromProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_RemoveProductFromProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + await client.remove_product_from_product_set(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_RemoveProductFromProductSet_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_remove_product_from_product_set_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_remove_product_from_product_set_sync.py new file mode 100644 index 00000000..aae122c6 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_remove_product_from_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for RemoveProductFromProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_RemoveProductFromProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_remove_product_from_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.RemoveProductFromProductSetRequest( + name="name_value", + product="product_value", + ) + + # Make the request + client.remove_product_from_product_set(request=request) + + +# [END vision_v1p4beta1_generated_ProductSearch_RemoveProductFromProductSet_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_async.py new file mode 100644 index 00000000..58727261 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_UpdateProduct_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_update_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.UpdateProductRequest( + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_UpdateProduct_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_set_async.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_set_async.py new file mode 100644 index 00000000..7bcda73b --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_set_async.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_UpdateProductSet_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +async def sample_update_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchAsyncClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.UpdateProductSetRequest( + ) + + # Make the request + response = await client.update_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_UpdateProductSet_async] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_set_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_set_sync.py new file mode 100644 index 00000000..4c9daa69 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_set_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProductSet +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_UpdateProductSet_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_update_product_set(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.UpdateProductSetRequest( + ) + + # Make the request + response = client.update_product_set(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_UpdateProductSet_sync] diff --git a/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_sync.py b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_sync.py new file mode 100644 index 00000000..fd1194b9 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/samples/generated_samples/vision_v1p4beta1_generated_product_search_update_product_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateProduct +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-vision + + +# [START vision_v1p4beta1_generated_ProductSearch_UpdateProduct_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import vision_v1p4beta1 + + +def sample_update_product(): + # Create a client + client = vision_v1p4beta1.ProductSearchClient() + + # Initialize request argument(s) + request = vision_v1p4beta1.UpdateProductRequest( + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + +# [END vision_v1p4beta1_generated_ProductSearch_UpdateProduct_sync] diff --git a/owl-bot-staging/v1p4beta1/scripts/fixup_vision_v1p4beta1_keywords.py b/owl-bot-staging/v1p4beta1/scripts/fixup_vision_v1p4beta1_keywords.py new file mode 100644 index 00000000..44d1c4d2 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/scripts/fixup_vision_v1p4beta1_keywords.py @@ -0,0 +1,198 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import argparse +import os +import libcst as cst +import pathlib +import sys +from typing import (Any, Callable, Dict, List, Sequence, Tuple) + + +def partition( + predicate: Callable[[Any], bool], + iterator: Sequence[Any] +) -> Tuple[List[Any], List[Any]]: + """A stable, out-of-place partition.""" + results = ([], []) + + for i in iterator: + results[int(predicate(i))].append(i) + + # Returns trueList, falseList + return results[1], results[0] + + +class visionCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'add_product_to_product_set': ('name', 'product', ), + 'async_batch_annotate_files': ('requests', ), + 'async_batch_annotate_images': ('requests', 'output_config', ), + 'batch_annotate_files': ('requests', ), + 'batch_annotate_images': ('requests', ), + 'create_product': ('parent', 'product', 'product_id', ), + 'create_product_set': ('parent', 'product_set', 'product_set_id', ), + 'create_reference_image': ('parent', 'reference_image', 'reference_image_id', ), + 'delete_product': ('name', ), + 'delete_product_set': ('name', ), + 'delete_reference_image': ('name', ), + 'get_product': ('name', ), + 'get_product_set': ('name', ), + 'get_reference_image': ('name', ), + 'import_product_sets': ('parent', 'input_config', ), + 'list_products': ('parent', 'page_size', 'page_token', ), + 'list_product_sets': ('parent', 'page_size', 'page_token', ), + 'list_products_in_product_set': ('name', 'page_size', 'page_token', ), + 'list_reference_images': ('parent', 'page_size', 'page_token', ), + 'purge_products': ('parent', 'product_set_purge_config', 'delete_orphan_products', 'force', ), + 'remove_product_from_product_set': ('name', 'product', ), + 'update_product': ('product', 'update_mask', ), + 'update_product_set': ('product_set', 'update_mask', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=visionCallTransformer(), +): + """Duplicate the input dir to the output dir, fixing file method calls. + + Preconditions: + * in_dir is a real directory + * out_dir is a real, empty directory + """ + pyfile_gen = ( + pathlib.Path(os.path.join(root, f)) + for root, _, files in os.walk(in_dir) + for f in files if os.path.splitext(f)[1] == ".py" + ) + + for fpath in pyfile_gen: + with open(fpath, 'r') as f: + src = f.read() + + # Parse the code and insert method call fixes. + tree = cst.parse_module(src) + updated = tree.visit(transformer) + + # Create the path and directory structure for the new file. + updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) + updated_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate the updated source file at the corresponding path. + with open(updated_path, 'w') as f: + f.write(updated.code) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Fix up source that uses the vision client library. + +The existing sources are NOT overwritten but are copied to output_dir with changes made. + +Note: This tool operates at a best-effort level at converting positional + parameters in client method calls to keyword based parameters. + Cases where it WILL FAIL include + A) * or ** expansion in a method call. + B) Calls via function or method alias (includes free function calls) + C) Indirect or dispatched calls (e.g. the method is looked up dynamically) + + These all constitute false negatives. The tool will also detect false + positives when an API method shares a name with another method. +""") + parser.add_argument( + '-d', + '--input-directory', + required=True, + dest='input_dir', + help='the input directory to walk for python files to fix up', + ) + parser.add_argument( + '-o', + '--output-directory', + required=True, + dest='output_dir', + help='the directory to output files fixed via un-flattening', + ) + args = parser.parse_args() + input_dir = pathlib.Path(args.input_dir) + output_dir = pathlib.Path(args.output_dir) + if not input_dir.is_dir(): + print( + f"input directory '{input_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if not output_dir.is_dir(): + print( + f"output directory '{output_dir}' does not exist or is not a directory", + file=sys.stderr, + ) + sys.exit(-1) + + if os.listdir(output_dir): + print( + f"output directory '{output_dir}' is not empty", + file=sys.stderr, + ) + sys.exit(-1) + + fix_files(input_dir, output_dir) diff --git a/owl-bot-staging/v1p4beta1/setup.py b/owl-bot-staging/v1p4beta1/setup.py new file mode 100644 index 00000000..7525c907 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/setup.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import io +import os + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-cloud-vision' + + +description = "Google Cloud Vision API client library" + +version = {} +with open(os.path.join(package_root, 'google/cloud/vision/gapic_version.py')) as fp: + exec(fp.read(), version) +version = version["__version__"] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.0, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "proto-plus >= 1.22.0, <2.0.0dev", + "proto-plus >= 1.22.2, <2.0.0dev; python_version>='3.11'", + "protobuf>=3.19.5,<5.0.0dev,!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/python-vision" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.PEP420PackageFinder.find() + if package.startswith("google") +] + +namespaces = ["google", "google.cloud"] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + namespace_packages=namespaces, + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/v1p4beta1/testing/constraints-3.10.txt b/owl-bot-staging/v1p4beta1/testing/constraints-3.10.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p4beta1/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p4beta1/testing/constraints-3.11.txt b/owl-bot-staging/v1p4beta1/testing/constraints-3.11.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p4beta1/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p4beta1/testing/constraints-3.12.txt b/owl-bot-staging/v1p4beta1/testing/constraints-3.12.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p4beta1/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p4beta1/testing/constraints-3.7.txt b/owl-bot-staging/v1p4beta1/testing/constraints-3.7.txt new file mode 100644 index 00000000..6c44adfe --- /dev/null +++ b/owl-bot-staging/v1p4beta1/testing/constraints-3.7.txt @@ -0,0 +1,9 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file. +# Pin the version to the lower bound. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", +# Then this file should have google-cloud-foo==1.14.0 +google-api-core==1.34.0 +proto-plus==1.22.0 +protobuf==3.19.5 diff --git a/owl-bot-staging/v1p4beta1/testing/constraints-3.8.txt b/owl-bot-staging/v1p4beta1/testing/constraints-3.8.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p4beta1/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p4beta1/testing/constraints-3.9.txt b/owl-bot-staging/v1p4beta1/testing/constraints-3.9.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v1p4beta1/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/v1p4beta1/tests/__init__.py b/owl-bot-staging/v1p4beta1/tests/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p4beta1/tests/unit/__init__.py b/owl-bot-staging/v1p4beta1/tests/unit/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p4beta1/tests/unit/gapic/__init__.py b/owl-bot-staging/v1p4beta1/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/__init__.py b/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/test_image_annotator.py b/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/test_image_annotator.py new file mode 100644 index 00000000..19502466 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/test_image_annotator.py @@ -0,0 +1,2901 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule +from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.vision_v1p4beta1.services.image_annotator import ImageAnnotatorAsyncClient +from google.cloud.vision_v1p4beta1.services.image_annotator import ImageAnnotatorClient +from google.cloud.vision_v1p4beta1.services.image_annotator import transports +from google.cloud.vision_v1p4beta1.types import face +from google.cloud.vision_v1p4beta1.types import geometry +from google.cloud.vision_v1p4beta1.types import image_annotator +from google.cloud.vision_v1p4beta1.types import product_search +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.type import latlng_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ImageAnnotatorClient._get_default_mtls_endpoint(None) is None + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ImageAnnotatorClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ImageAnnotatorGrpcTransport, "grpc"), + (transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ImageAnnotatorClient, "grpc"), + (ImageAnnotatorAsyncClient, "grpc_asyncio"), + (ImageAnnotatorClient, "rest"), +]) +def test_image_annotator_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +def test_image_annotator_client_get_transport_class(): + transport = ImageAnnotatorClient.get_transport_class() + available_transports = [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorRestTransport, + ] + assert transport in available_transports + + transport = ImageAnnotatorClient.get_transport_class("grpc") + assert transport == transports.ImageAnnotatorGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ImageAnnotatorClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "true"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", "false"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "true"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", "false"), +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_image_annotator_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + ImageAnnotatorClient, ImageAnnotatorAsyncClient +]) +@mock.patch.object(ImageAnnotatorClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorClient)) +@mock.patch.object(ImageAnnotatorAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ImageAnnotatorAsyncClient)) +def test_image_annotator_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc"), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio"), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest"), +]) +def test_image_annotator_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ImageAnnotatorClient, transports.ImageAnnotatorRestTransport, "rest", None), +]) +def test_image_annotator_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_image_annotator_client_client_options_from_dict(): + with mock.patch('google.cloud.vision_v1p4beta1.services.image_annotator.transports.ImageAnnotatorGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ImageAnnotatorClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport, "grpc", grpc_helpers), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_image_annotator_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=None, + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse( + ) + response = client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + client.batch_annotate_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + +@pytest.mark.asyncio +async def test_batch_annotate_images_async(transport: str = 'grpc_asyncio', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse( + )) + response = await client.batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +@pytest.mark.asyncio +async def test_batch_annotate_images_async_from_dict(): + await test_batch_annotate_images_async(request_type=dict) + + +def test_batch_annotate_images_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + + +def test_batch_annotate_images_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateImagesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateImagesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_annotate_images_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateFilesRequest, + dict, +]) +def test_batch_annotate_files(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateFilesResponse( + ) + response = client.batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateFilesResponse) + + +def test_batch_annotate_files_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + client.batch_annotate_files() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateFilesRequest() + +@pytest.mark.asyncio +async def test_batch_annotate_files_async(transport: str = 'grpc_asyncio', request_type=image_annotator.BatchAnnotateFilesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateFilesResponse( + )) + response = await client.batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.BatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateFilesResponse) + + +@pytest.mark.asyncio +async def test_batch_annotate_files_async_from_dict(): + await test_batch_annotate_files_async(request_type=dict) + + +def test_batch_annotate_files_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateFilesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_annotate_files( + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + + +def test_batch_annotate_files_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_files( + image_annotator.BatchAnnotateFilesRequest(), + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + +@pytest.mark.asyncio +async def test_batch_annotate_files_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = image_annotator.BatchAnnotateFilesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(image_annotator.BatchAnnotateFilesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_annotate_files( + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_annotate_files_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_annotate_files( + image_annotator.BatchAnnotateFilesRequest(), + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateImagesRequest, + dict, +]) +def test_async_batch_annotate_images(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.async_batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_async_batch_annotate_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + client.async_batch_annotate_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateImagesRequest() + +@pytest.mark.asyncio +async def test_async_batch_annotate_images_async(transport: str = 'grpc_asyncio', request_type=image_annotator.AsyncBatchAnnotateImagesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.async_batch_annotate_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_async_batch_annotate_images_async_from_dict(): + await test_async_batch_annotate_images_async(request_type=dict) + + +def test_async_batch_annotate_images_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.async_batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + arg = args[0].output_config + mock_val = image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')) + assert arg == mock_val + + +def test_async_batch_annotate_images_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_images( + image_annotator.AsyncBatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + +@pytest.mark.asyncio +async def test_async_batch_annotate_images_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.async_batch_annotate_images( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))] + assert arg == mock_val + arg = args[0].output_config + mock_val = image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_async_batch_annotate_images_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.async_batch_annotate_images( + image_annotator.AsyncBatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateFilesRequest, + dict, +]) +def test_async_batch_annotate_files(request_type, transport: str = 'grpc'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.async_batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_async_batch_annotate_files_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + client.async_batch_annotate_files() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_async(transport: str = 'grpc_asyncio', request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.async_batch_annotate_files(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == image_annotator.AsyncBatchAnnotateFilesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_async_from_dict(): + await test_async_batch_annotate_files_async(request_type=dict) + + +def test_async_batch_annotate_files_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.async_batch_annotate_files( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + + +def test_async_batch_annotate_files_flattened_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_flattened_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.async_batch_annotate_files), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.async_batch_annotate_files( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].requests + mock_val = [image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_async_batch_annotate_files_flattened_error_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateImagesRequest, + dict, +]) +def test_batch_annotate_images_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_annotate_images(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateImagesResponse) + + +def test_batch_annotate_images_rest_required_fields(request_type=image_annotator.BatchAnnotateImagesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_annotate_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_annotate_images_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_annotate_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_annotate_images_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_batch_annotate_images") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_batch_annotate_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.BatchAnnotateImagesRequest.pb(image_annotator.BatchAnnotateImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = image_annotator.BatchAnnotateImagesResponse.to_json(image_annotator.BatchAnnotateImagesResponse()) + + request = image_annotator.BatchAnnotateImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = image_annotator.BatchAnnotateImagesResponse() + + client.batch_annotate_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_annotate_images_rest_bad_request(transport: str = 'rest', request_type=image_annotator.BatchAnnotateImagesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.batch_annotate_images(request) + + +def test_batch_annotate_images_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateImagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_annotate_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/images:annotate" % client.transport._host, args[1]) + + +def test_batch_annotate_images_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_images( + image_annotator.BatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + ) + + +def test_batch_annotate_images_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.BatchAnnotateFilesRequest, + dict, +]) +def test_batch_annotate_files_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateFilesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateFilesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_annotate_files(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, image_annotator.BatchAnnotateFilesResponse) + + +def test_batch_annotate_files_rest_required_fields(request_type=image_annotator.BatchAnnotateFilesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateFilesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateFilesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_annotate_files(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_annotate_files_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_annotate_files._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_annotate_files_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_batch_annotate_files") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_batch_annotate_files") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.BatchAnnotateFilesRequest.pb(image_annotator.BatchAnnotateFilesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = image_annotator.BatchAnnotateFilesResponse.to_json(image_annotator.BatchAnnotateFilesResponse()) + + request = image_annotator.BatchAnnotateFilesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = image_annotator.BatchAnnotateFilesResponse() + + client.batch_annotate_files(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_annotate_files_rest_bad_request(transport: str = 'rest', request_type=image_annotator.BatchAnnotateFilesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.batch_annotate_files(request) + + +def test_batch_annotate_files_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = image_annotator.BatchAnnotateFilesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = image_annotator.BatchAnnotateFilesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_annotate_files(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/files:annotate" % client.transport._host, args[1]) + + +def test_batch_annotate_files_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_annotate_files( + image_annotator.BatchAnnotateFilesRequest(), + requests=[image_annotator.AnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +def test_batch_annotate_files_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateImagesRequest, + dict, +]) +def test_async_batch_annotate_images_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.async_batch_annotate_images(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_async_batch_annotate_images_rest_required_fields(request_type=image_annotator.AsyncBatchAnnotateImagesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.async_batch_annotate_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_async_batch_annotate_images_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.async_batch_annotate_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", "outputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_async_batch_annotate_images_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_async_batch_annotate_images") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_async_batch_annotate_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.AsyncBatchAnnotateImagesRequest.pb(image_annotator.AsyncBatchAnnotateImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = image_annotator.AsyncBatchAnnotateImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.async_batch_annotate_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_async_batch_annotate_images_rest_bad_request(transport: str = 'rest', request_type=image_annotator.AsyncBatchAnnotateImagesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.async_batch_annotate_images(request) + + +def test_async_batch_annotate_images_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.async_batch_annotate_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/images:asyncBatchAnnotate" % client.transport._host, args[1]) + + +def test_async_batch_annotate_images_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_images( + image_annotator.AsyncBatchAnnotateImagesRequest(), + requests=[image_annotator.AnnotateImageRequest(image=image_annotator.Image(content=b'content_blob'))], + output_config=image_annotator.OutputConfig(gcs_destination=image_annotator.GcsDestination(uri='uri_value')), + ) + + +def test_async_batch_annotate_images_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + image_annotator.AsyncBatchAnnotateFilesRequest, + dict, +]) +def test_async_batch_annotate_files_rest(request_type): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.async_batch_annotate_files(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_async_batch_annotate_files_rest_required_fields(request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + transport_class = transports.ImageAnnotatorRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).async_batch_annotate_files._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.async_batch_annotate_files(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_async_batch_annotate_files_rest_unset_required_fields(): + transport = transports.ImageAnnotatorRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.async_batch_annotate_files._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("requests", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_async_batch_annotate_files_rest_interceptors(null_interceptor): + transport = transports.ImageAnnotatorRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ImageAnnotatorRestInterceptor(), + ) + client = ImageAnnotatorClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "post_async_batch_annotate_files") as post, \ + mock.patch.object(transports.ImageAnnotatorRestInterceptor, "pre_async_batch_annotate_files") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = image_annotator.AsyncBatchAnnotateFilesRequest.pb(image_annotator.AsyncBatchAnnotateFilesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = image_annotator.AsyncBatchAnnotateFilesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.async_batch_annotate_files(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_async_batch_annotate_files_rest_bad_request(transport: str = 'rest', request_type=image_annotator.AsyncBatchAnnotateFilesRequest): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.async_batch_annotate_files(request) + + +def test_async_batch_annotate_files_rest_flattened(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {} + + # get truthy value for each flattened field + mock_args = dict( + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.async_batch_annotate_files(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/files:asyncBatchAnnotate" % client.transport._host, args[1]) + + +def test_async_batch_annotate_files_rest_flattened_error(transport: str = 'rest'): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.async_batch_annotate_files( + image_annotator.AsyncBatchAnnotateFilesRequest(), + requests=[image_annotator.AsyncAnnotateFileRequest(input_config=image_annotator.InputConfig(gcs_source=image_annotator.GcsSource(uri='uri_value')))], + ) + + +def test_async_batch_annotate_files_rest_error(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ImageAnnotatorClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ImageAnnotatorClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ImageAnnotatorGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "rest", +]) +def test_transport_kind(transport_name): + transport = ImageAnnotatorClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ImageAnnotatorGrpcTransport, + ) + +def test_image_annotator_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_image_annotator_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.vision_v1p4beta1.services.image_annotator.transports.ImageAnnotatorTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ImageAnnotatorTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'batch_annotate_images', + 'batch_annotate_files', + 'async_batch_annotate_images', + 'async_batch_annotate_files', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_image_annotator_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.vision_v1p4beta1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id="octopus", + ) + + +def test_image_annotator_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.vision_v1p4beta1.services.image_annotator.transports.ImageAnnotatorTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ImageAnnotatorTransport() + adc.assert_called_once() + + +def test_image_annotator_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ImageAnnotatorClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + ], +) +def test_image_annotator_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-vision',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ImageAnnotatorGrpcTransport, + transports.ImageAnnotatorGrpcAsyncIOTransport, + transports.ImageAnnotatorRestTransport, + ], +) +def test_image_annotator_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ImageAnnotatorGrpcTransport, grpc_helpers), + (transports.ImageAnnotatorGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_image_annotator_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=["1", "2"], + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_image_annotator_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel") as mock_configure_mtls_channel: + transports.ImageAnnotatorRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_image_annotator_rest_lro_client(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_no_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_image_annotator_host_with_port(transport_name): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_image_annotator_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ImageAnnotatorClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ImageAnnotatorClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.batch_annotate_images._session + session2 = client2.transport.batch_annotate_images._session + assert session1 != session2 + session1 = client1.transport.batch_annotate_files._session + session2 = client2.transport.batch_annotate_files._session + assert session1 != session2 + session1 = client1.transport.async_batch_annotate_images._session + session2 = client2.transport.async_batch_annotate_images._session + assert session1 != session2 + session1 = client1.transport.async_batch_annotate_files._session + session2 = client2.transport.async_batch_annotate_files._session + assert session1 != session2 +def test_image_annotator_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_image_annotator_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ImageAnnotatorGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ImageAnnotatorGrpcTransport, transports.ImageAnnotatorGrpcAsyncIOTransport]) +def test_image_annotator_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_image_annotator_grpc_lro_client(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_image_annotator_grpc_lro_async_client(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_path(): + project = "squid" + location = "clam" + product = "whelk" + expected = "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + actual = ImageAnnotatorClient.product_path(project, location, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "octopus", + "location": "oyster", + "product": "nudibranch", + } + path = ImageAnnotatorClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_product_path(path) + assert expected == actual + +def test_product_set_path(): + project = "cuttlefish" + location = "mussel" + product_set = "winkle" + expected = "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + actual = ImageAnnotatorClient.product_set_path(project, location, product_set) + assert expected == actual + + +def test_parse_product_set_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "product_set": "abalone", + } + path = ImageAnnotatorClient.product_set_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_product_set_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ImageAnnotatorClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = ImageAnnotatorClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder, ) + actual = ImageAnnotatorClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = ImageAnnotatorClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ImageAnnotatorClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = ImageAnnotatorClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project, ) + actual = ImageAnnotatorClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = ImageAnnotatorClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ImageAnnotatorClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = ImageAnnotatorClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ImageAnnotatorClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ImageAnnotatorTransport, '_prep_wrapped_messages') as prep: + transport_class = ImageAnnotatorClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ImageAnnotatorAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = ImageAnnotatorClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ImageAnnotatorClient, transports.ImageAnnotatorGrpcTransport), + (ImageAnnotatorAsyncClient, transports.ImageAnnotatorGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/test_product_search.py b/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/test_product_search.py new file mode 100644 index 00000000..dfbeaa87 --- /dev/null +++ b/owl-bot-staging/v1p4beta1/tests/unit/gapic/vision_v1p4beta1/test_product_search.py @@ -0,0 +1,11710 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed 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. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json +import math +import pytest +from proto.marshal.rules.dates import DurationRule, TimestampRule +from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import future +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import operation +from google.api_core import operation_async # type: ignore +from google.api_core import operations_v1 +from google.api_core import path_template +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.vision_v1p4beta1.services.product_search import ProductSearchAsyncClient +from google.cloud.vision_v1p4beta1.services.product_search import ProductSearchClient +from google.cloud.vision_v1p4beta1.services.product_search import pagers +from google.cloud.vision_v1p4beta1.services.product_search import transports +from google.cloud.vision_v1p4beta1.types import geometry +from google.cloud.vision_v1p4beta1.types import product_search_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +import google.auth + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ProductSearchClient._get_default_mtls_endpoint(None) is None + assert ProductSearchClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ProductSearchClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductSearchClient, "grpc"), + (ProductSearchAsyncClient, "grpc_asyncio"), + (ProductSearchClient, "rest"), +]) +def test_product_search_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ProductSearchGrpcTransport, "grpc"), + (transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ProductSearchRestTransport, "rest"), +]) +def test_product_search_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductSearchClient, "grpc"), + (ProductSearchAsyncClient, "grpc_asyncio"), + (ProductSearchClient, "rest"), +]) +def test_product_search_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://vision.googleapis.com' + ) + + +def test_product_search_client_get_transport_class(): + transport = ProductSearchClient.get_transport_class() + available_transports = [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchRestTransport, + ] + assert transport in available_transports + + transport = ProductSearchClient.get_transport_class("grpc") + assert transport == transports.ProductSearchGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest"), +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +def test_product_search_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ProductSearchClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ProductSearchClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError): + client = client_class(transport=transport_name) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError): + client = client_class(transport=transport_name) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", "true"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", "false"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", "true"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", "false"), +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_product_search_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + ProductSearchClient, ProductSearchAsyncClient +]) +@mock.patch.object(ProductSearchClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchClient)) +@mock.patch.object(ProductSearchAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductSearchAsyncClient)) +def test_product_search_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc"), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest"), +]) +def test_product_search_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", grpc_helpers), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ProductSearchClient, transports.ProductSearchRestTransport, "rest", None), +]) +def test_product_search_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_product_search_client_client_options_from_dict(): + with mock.patch('google.cloud.vision_v1p4beta1.services.product_search.transports.ProductSearchGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ProductSearchClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport, "grpc", grpc_helpers), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_product_search_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=None, + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductSetRequest, + dict, +]) +def test_create_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_create_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + client.create_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + +@pytest.mark.asyncio +async def test_create_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_create_product_set_async_from_dict(): + await test_create_product_set_async(request_type=dict) + + +def test_create_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductSetRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductSetRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.create_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_product_set( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].product_set_id + mock_val = 'product_set_id_value' + assert arg == mock_val + + +def test_create_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_product_set( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].product_set_id + mock_val = 'product_set_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductSetsRequest, + dict, +]) +def test_list_product_sets(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_product_sets_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + client.list_product_sets() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + +@pytest.mark.asyncio +async def test_list_product_sets_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductSetsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_product_sets_async_from_dict(): + await test_list_product_sets_async(request_type=dict) + + +def test_list_product_sets_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + call.return_value = product_search_service.ListProductSetsResponse() + client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_product_sets_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse()) + await client.list_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_product_sets_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_product_sets( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_product_sets_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_product_sets_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductSetsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductSetsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_product_sets( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_product_sets_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + + +def test_list_product_sets_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_product_sets(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in results) +def test_list_product_sets_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + pages = list(client.list_product_sets(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_product_sets_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_product_sets(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_product_sets_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_product_sets), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_product_sets(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductSetRequest, + dict, +]) +def test_get_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_get_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + client.get_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + +@pytest.mark.asyncio +async def test_get_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_get_product_set_async_from_dict(): + await test_get_product_set_async(request_type=dict) + + +def test_get_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.get_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductSetRequest, + dict, +]) +def test_update_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + response = client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + client.update_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + +@pytest.mark.asyncio +async def test_update_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.UpdateProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + )) + response = await client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_update_product_set_async_from_dict(): + await test_update_product_set_async(request_type=dict) + + +def test_update_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductSetRequest() + + request.product_set.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + call.return_value = product_search_service.ProductSet() + client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product_set.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductSetRequest() + + request.product_set.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + await client.update_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product_set.name=name_value', + ) in kw['metadata'] + + +def test_update_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product_set( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_update_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ProductSet() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ProductSet()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_product_set( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].product_set + mock_val = product_search_service.ProductSet(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_update_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductSetRequest, + dict, +]) +def test_delete_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + client.delete_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + +@pytest.mark.asyncio +async def test_delete_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_product_set_async_from_dict(): + await test_delete_product_set_async(request_type=dict) + + +def test_delete_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + call.return_value = None + client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductRequest, + dict, +]) +def test_create_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_create_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + client.create_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + +@pytest.mark.asyncio +async def test_create_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_create_product_async_from_dict(): + await test_create_product_async(request_type=dict) + + +def test_create_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateProductRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.create_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_product( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].product_id + mock_val = 'product_id_value' + assert arg == mock_val + + +def test_create_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_product( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].product_id + mock_val = 'product_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsRequest, + dict, +]) +def test_list_products(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + client.list_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + +@pytest.mark.asyncio +async def test_list_products_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_products_async_from_dict(): + await test_list_products_async(request_type=dict) + + +def test_list_products_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + call.return_value = product_search_service.ListProductsResponse() + client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_products_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse()) + await client.list_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_products_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_products_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_products_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_products_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_products(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) +def test_list_products_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = list(client.list_products(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_products_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_products(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_products(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductRequest, + dict, +]) +def test_get_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_get_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + client.get_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + +@pytest.mark.asyncio +async def test_get_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_get_product_async_from_dict(): + await test_get_product_async(request_type=dict) + + +def test_get_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.get_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductRequest, + dict, +]) +def test_update_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + response = client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_update_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + client.update_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + +@pytest.mark.asyncio +async def test_update_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.UpdateProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + )) + response = await client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +@pytest.mark.asyncio +async def test_update_product_async_from_dict(): + await test_update_product_async(request_type=dict) + + +def test_update_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductRequest() + + request.product.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + call.return_value = product_search_service.Product() + client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.UpdateProductRequest() + + request.product.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + await client.update_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'product.name=name_value', + ) in kw['metadata'] + + +def test_update_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_update_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.Product()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_product( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].product + mock_val = product_search_service.Product(name='name_value') + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_update_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductRequest, + dict, +]) +def test_delete_product(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + client.delete_product() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + +@pytest.mark.asyncio +async def test_delete_product_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteProductRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteProductRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_product_async_from_dict(): + await test_delete_product_async(request_type=dict) + + +def test_delete_product_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + call.return_value = None + client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_product_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteProductRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_product(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_product_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_product_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_product), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_product( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_product_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateReferenceImageRequest, + dict, +]) +def test_create_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + response = client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_create_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + client.create_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + +@pytest.mark.asyncio +async def test_create_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.CreateReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + )) + response = await client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.CreateReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +@pytest.mark.asyncio +async def test_create_reference_image_async_from_dict(): + await test_create_reference_image_async(request_type=dict) + + +def test_create_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateReferenceImageRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + call.return_value = product_search_service.ReferenceImage() + client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_create_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.CreateReferenceImageRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + await client.create_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_create_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_reference_image( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].reference_image + mock_val = product_search_service.ReferenceImage(name='name_value') + assert arg == mock_val + arg = args[0].reference_image_id + mock_val = 'reference_image_id_value' + assert arg == mock_val + + +def test_create_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + +@pytest.mark.asyncio +async def test_create_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_reference_image( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].reference_image + mock_val = product_search_service.ReferenceImage(name='name_value') + assert arg == mock_val + arg = args[0].reference_image_id + mock_val = 'reference_image_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteReferenceImageRequest, + dict, +]) +def test_delete_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + client.delete_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + +@pytest.mark.asyncio +async def test_delete_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.DeleteReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.DeleteReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_reference_image_async_from_dict(): + await test_delete_reference_image_async(request_type=dict) + + +def test_delete_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + call.return_value = None + client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_delete_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.DeleteReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_delete_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_delete_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_delete_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListReferenceImagesRequest, + dict, +]) +def test_list_reference_images(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + ) + response = client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +def test_list_reference_images_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + client.list_reference_images() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + +@pytest.mark.asyncio +async def test_list_reference_images_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListReferenceImagesRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + )) + response = await client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListReferenceImagesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesAsyncPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_reference_images_async_from_dict(): + await test_list_reference_images_async(request_type=dict) + + +def test_list_reference_images_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListReferenceImagesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + call.return_value = product_search_service.ListReferenceImagesResponse() + client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_reference_images_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListReferenceImagesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse()) + await client.list_reference_images(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_list_reference_images_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_reference_images( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_list_reference_images_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_reference_images_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListReferenceImagesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListReferenceImagesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_reference_images( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_reference_images_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + + +def test_list_reference_images_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_reference_images(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in results) +def test_list_reference_images_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + pages = list(client.list_reference_images(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_reference_images_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_reference_images(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_reference_images_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_reference_images), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_reference_images(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetReferenceImageRequest, + dict, +]) +def test_get_reference_image(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + response = client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_get_reference_image_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + client.get_reference_image() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + +@pytest.mark.asyncio +async def test_get_reference_image_async(transport: str = 'grpc_asyncio', request_type=product_search_service.GetReferenceImageRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + )) + response = await client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.GetReferenceImageRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +@pytest.mark.asyncio +async def test_get_reference_image_async_from_dict(): + await test_get_reference_image_async(request_type=dict) + + +def test_get_reference_image_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + call.return_value = product_search_service.ReferenceImage() + client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_reference_image_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.GetReferenceImageRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + await client.get_reference_image(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_get_reference_image_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_get_reference_image_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_reference_image_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_reference_image), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ReferenceImage() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ReferenceImage()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_reference_image( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_reference_image_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.AddProductToProductSetRequest, + dict, +]) +def test_add_product_to_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_add_product_to_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + client.add_product_to_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + +@pytest.mark.asyncio +async def test_add_product_to_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.AddProductToProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.AddProductToProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_add_product_to_product_set_async_from_dict(): + await test_add_product_to_product_set_async(request_type=dict) + + +def test_add_product_to_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.AddProductToProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + call.return_value = None + client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_product_to_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.AddProductToProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.add_product_to_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_add_product_to_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.add_product_to_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_product_to_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_product_to_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_product_to_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.add_product_to_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_product_to_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.RemoveProductFromProductSetRequest, + dict, +]) +def test_remove_product_from_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_remove_product_from_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + client.remove_product_from_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.RemoveProductFromProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.RemoveProductFromProductSetRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_async_from_dict(): + await test_remove_product_from_product_set_async(request_type=dict) + + +def test_remove_product_from_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.RemoveProductFromProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + call.return_value = None + client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.RemoveProductFromProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.remove_product_from_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_remove_product_from_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.remove_product_from_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_product_from_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_product_from_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.remove_product_from_product_set( + name='name_value', + product='product_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_product_from_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsInProductSetRequest, + dict, +]) +def test_list_products_in_product_set(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + ) + response = client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_in_product_set_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + client.list_products_in_product_set() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ListProductsInProductSetRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ListProductsInProductSetRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_from_dict(): + await test_list_products_in_product_set_async(request_type=dict) + + +def test_list_products_in_product_set_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsInProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + call.return_value = product_search_service.ListProductsInProductSetResponse() + client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ListProductsInProductSetRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse()) + await client.list_products_in_product_set(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_list_products_in_product_set_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_products_in_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + + +def test_list_products_in_product_set_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_list_products_in_product_set_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = product_search_service.ListProductsInProductSetResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_search_service.ListProductsInProductSetResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_products_in_product_set( + name='name_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_products_in_product_set_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + + +def test_list_products_in_product_set_pager(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('name', ''), + )), + ) + pager = client.list_products_in_product_set(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) +def test_list_products_in_product_set_pages(transport_name: str = "grpc"): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials, + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = list(client.list_products_in_product_set(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_pager(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_products_in_product_set(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_in_product_set_async_pages(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_products_in_product_set), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_products_in_product_set(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.parametrize("request_type", [ + product_search_service.ImportProductSetsRequest, + dict, +]) +def test_import_product_sets(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_product_sets_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + client.import_product_sets() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + +@pytest.mark.asyncio +async def test_import_product_sets_async(transport: str = 'grpc_asyncio', request_type=product_search_service.ImportProductSetsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.ImportProductSetsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_product_sets_async_from_dict(): + await test_import_product_sets_async(request_type=dict) + + +def test_import_product_sets_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ImportProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_import_product_sets_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.ImportProductSetsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_product_sets(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_import_product_sets_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.import_product_sets( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].input_config + mock_val = product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')) + assert arg == mock_val + + +def test_import_product_sets_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + +@pytest.mark.asyncio +async def test_import_product_sets_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_product_sets), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.import_product_sets( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].input_config + mock_val = product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_import_product_sets_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.PurgeProductsRequest, + dict, +]) +def test_purge_products(request_type, transport: str = 'grpc'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.purge_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.PurgeProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_purge_products_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + client.purge_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.PurgeProductsRequest() + +@pytest.mark.asyncio +async def test_purge_products_async(transport: str = 'grpc_asyncio', request_type=product_search_service.PurgeProductsRequest): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + response = await client.purge_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_search_service.PurgeProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_purge_products_async_from_dict(): + await test_purge_products_async(request_type=dict) + + +def test_purge_products_field_headers(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.PurgeProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.purge_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_purge_products_field_headers_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = product_search_service.PurgeProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.purge_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_purge_products_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.purge_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + + +def test_purge_products_flattened_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.purge_products( + product_search_service.PurgeProductsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_purge_products_flattened_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/op') + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name='operations/spam') + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.purge_products( + parent='parent_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = 'parent_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_purge_products_flattened_error_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.purge_products( + product_search_service.PurgeProductsRequest(), + parent='parent_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductSetRequest, + dict, +]) +def test_create_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request_init["product_set"] = {'name': 'name_value', 'display_name': 'display_name_value', 'index_time': {'seconds': 751, 'nanos': 543}, 'index_error': {'code': 411, 'message': 'message_value', 'details': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}]}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateProductSetRequest.meta.fields["product_set"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product_set"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product_set"][field])): + del request_init["product_set"][field][i][subfield] + else: + del request_init["product_set"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_create_product_set_rest_required_fields(request_type=product_search_service.CreateProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("product_set_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productSetId", )) & set(("parent", "productSet", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateProductSetRequest.pb(product_search_service.CreateProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.CreateProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.create_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_product_set(request) + + +def test_create_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{parent=projects/*/locations/*}/productSets" % client.transport._host, args[1]) + + +def test_create_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product_set( + product_search_service.CreateProductSetRequest(), + parent='parent_value', + product_set=product_search_service.ProductSet(name='name_value'), + product_set_id='product_set_id_value', + ) + + +def test_create_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductSetsRequest, + dict, +]) +def test_list_product_sets_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_product_sets(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductSetsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_product_sets_rest_required_fields(request_type=product_search_service.ListProductSetsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_product_sets._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_product_sets(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_product_sets_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_product_sets._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_product_sets_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_product_sets") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_product_sets") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductSetsRequest.pb(product_search_service.ListProductSetsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductSetsResponse.to_json(product_search_service.ListProductSetsResponse()) + + request = product_search_service.ListProductSetsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductSetsResponse() + + client.list_product_sets(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_product_sets_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductSetsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_product_sets(request) + + +def test_list_product_sets_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductSetsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductSetsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_product_sets(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{parent=projects/*/locations/*}/productSets" % client.transport._host, args[1]) + + +def test_list_product_sets_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_product_sets( + product_search_service.ListProductSetsRequest(), + parent='parent_value', + ) + + +def test_list_product_sets_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + next_page_token='abc', + ), + product_search_service.ListProductSetsResponse( + product_sets=[], + next_page_token='def', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductSetsResponse( + product_sets=[ + product_search_service.ProductSet(), + product_search_service.ProductSet(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductSetsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + pager = client.list_product_sets(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ProductSet) + for i in results) + + pages = list(client.list_product_sets(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductSetRequest, + dict, +]) +def test_get_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_get_product_set_rest_required_fields(request_type=product_search_service.GetProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetProductSetRequest.pb(product_search_service.GetProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.GetProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.get_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_product_set(request) + + +def test_get_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_get_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product_set( + product_search_service.GetProductSetRequest(), + name='name_value', + ) + + +def test_get_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductSetRequest, + dict, +]) +def test_update_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + request_init["product_set"] = {'name': 'projects/sample1/locations/sample2/productSets/sample3', 'display_name': 'display_name_value', 'index_time': {'seconds': 751, 'nanos': 543}, 'index_error': {'code': 411, 'message': 'message_value', 'details': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}]}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.UpdateProductSetRequest.meta.fields["product_set"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product_set"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product_set"][field])): + del request_init["product_set"][field][i][subfield] + else: + del request_init["product_set"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ProductSet) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_product_set_rest_required_fields(request_type=product_search_service.UpdateProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "patch", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("productSet", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_update_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_update_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.UpdateProductSetRequest.pb(product_search_service.UpdateProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ProductSet.to_json(product_search_service.ProductSet()) + + request = product_search_service.UpdateProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ProductSet() + + client.update_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.UpdateProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_product_set(request) + + +def test_update_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ProductSet() + + # get arguments that satisfy an http rule for this method + sample_request = {'product_set': {'name': 'projects/sample1/locations/sample2/productSets/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ProductSet.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{product_set.name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_update_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product_set( + product_search_service.UpdateProductSetRequest(), + product_set=product_search_service.ProductSet(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductSetRequest, + dict, +]) +def test_delete_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_set_rest_required_fields(request_type=product_search_service.DeleteProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteProductSetRequest.pb(product_search_service.DeleteProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_product_set(request) + + +def test_delete_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/productSets/*}" % client.transport._host, args[1]) + + +def test_delete_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product_set( + product_search_service.DeleteProductSetRequest(), + name='name_value', + ) + + +def test_delete_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateProductRequest, + dict, +]) +def test_create_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request_init["product"] = {'name': 'name_value', 'display_name': 'display_name_value', 'description': 'description_value', 'product_category': 'product_category_value', 'product_labels': [{'key': 'key_value', 'value': 'value_value'}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateProductRequest.meta.fields["product"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product"][field])): + del request_init["product"][field][i][subfield] + else: + del request_init["product"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_create_product_rest_required_fields(request_type=product_search_service.CreateProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_product._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("product_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productId", )) & set(("parent", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateProductRequest.pb(product_search_service.CreateProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.CreateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.create_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_product(request) + + +def test_create_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{parent=projects/*/locations/*}/products" % client.transport._host, args[1]) + + +def test_create_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_product( + product_search_service.CreateProductRequest(), + parent='parent_value', + product=product_search_service.Product(name='name_value'), + product_id='product_id_value', + ) + + +def test_create_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsRequest, + dict, +]) +def test_list_products_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_products(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_rest_required_fields(request_type=product_search_service.ListProductsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_products(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_products_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_products") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductsRequest.pb(product_search_service.ListProductsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductsResponse.to_json(product_search_service.ListProductsResponse()) + + request = product_search_service.ListProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductsResponse() + + client.list_products(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_products_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_products(request) + + +def test_list_products_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_products(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{parent=projects/*/locations/*}/products" % client.transport._host, args[1]) + + +def test_list_products_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products( + product_search_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + pager = client.list_products(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) + + pages = list(client.list_products(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetProductRequest, + dict, +]) +def test_get_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_get_product_rest_required_fields(request_type=product_search_service.GetProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetProductRequest.pb(product_search_service.GetProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.GetProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.get_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_product(request) + + +def test_get_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_get_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_product( + product_search_service.GetProductRequest(), + name='name_value', + ) + + +def test_get_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.UpdateProductRequest, + dict, +]) +def test_update_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + request_init["product"] = {'name': 'projects/sample1/locations/sample2/products/sample3', 'display_name': 'display_name_value', 'description': 'description_value', 'product_category': 'product_category_value', 'product_labels': [{'key': 'key_value', 'value': 'value_value'}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.UpdateProductRequest.meta.fields["product"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["product"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["product"][field])): + del request_init["product"][field][i][subfield] + else: + del request_init["product"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product( + name='name_value', + display_name='display_name_value', + description='description_value', + product_category='product_category_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_product(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.Product) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.description == 'description_value' + assert response.product_category == 'product_category_value' + + +def test_update_product_rest_required_fields(request_type=product_search_service.UpdateProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_product._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "patch", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_update_product") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_update_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.UpdateProductRequest.pb(product_search_service.UpdateProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.Product.to_json(product_search_service.Product()) + + request = product_search_service.UpdateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.Product() + + client.update_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.UpdateProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_product(request) + + +def test_update_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'product': {'name': 'projects/sample1/locations/sample2/products/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.Product.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{product.name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_update_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_product( + product_search_service.UpdateProductRequest(), + product=product_search_service.Product(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteProductRequest, + dict, +]) +def test_delete_product_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_product(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_product_rest_required_fields(request_type=product_search_service.DeleteProductRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_product._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_product(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_product_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_product_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_product") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteProductRequest.pb(product_search_service.DeleteProductRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_product(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_product_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteProductRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_product(request) + + +def test_delete_product_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_product(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/products/*}" % client.transport._host, args[1]) + + +def test_delete_product_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_product( + product_search_service.DeleteProductRequest(), + name='name_value', + ) + + +def test_delete_product_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.CreateReferenceImageRequest, + dict, +]) +def test_create_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request_init["reference_image"] = {'name': 'name_value', 'uri': 'uri_value', 'bounding_polys': [{'vertices': [{'x': 120, 'y': 121}], 'normalized_vertices': [{'x': 0.12, 'y': 0.121}]}]} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = product_search_service.CreateReferenceImageRequest.meta.fields["reference_image"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + else: + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + for field, value in request_init["reference_image"].items(): + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + for subfield_to_delete in subfields_not_in_runtime: + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["reference_image"][field])): + del request_init["reference_image"][field][i][subfield] + else: + del request_init["reference_image"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_reference_image(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_create_reference_image_rest_required_fields(request_type=product_search_service.CreateReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_reference_image._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("reference_image_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(("referenceImageId", )) & set(("parent", "referenceImage", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_create_reference_image") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_create_reference_image") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.CreateReferenceImageRequest.pb(product_search_service.CreateReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ReferenceImage.to_json(product_search_service.ReferenceImage()) + + request = product_search_service.CreateReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ReferenceImage() + + client.create_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.CreateReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_reference_image(request) + + +def test_create_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{parent=projects/*/locations/*/products/*}/referenceImages" % client.transport._host, args[1]) + + +def test_create_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_reference_image( + product_search_service.CreateReferenceImageRequest(), + parent='parent_value', + reference_image=product_search_service.ReferenceImage(name='name_value'), + reference_image_id='reference_image_id_value', + ) + + +def test_create_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.DeleteReferenceImageRequest, + dict, +]) +def test_delete_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.delete_reference_image(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_reference_image_rest_required_fields(request_type=product_search_service.DeleteReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "delete", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.delete_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_delete_reference_image") as pre: + pre.assert_not_called() + pb_message = product_search_service.DeleteReferenceImageRequest.pb(product_search_service.DeleteReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.DeleteReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.DeleteReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_reference_image(request) + + +def test_delete_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.delete_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/products/*/referenceImages/*}" % client.transport._host, args[1]) + + +def test_delete_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_reference_image( + product_search_service.DeleteReferenceImageRequest(), + name='name_value', + ) + + +def test_delete_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListReferenceImagesRequest, + dict, +]) +def test_list_reference_images_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse( + page_size=951, + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_reference_images(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListReferenceImagesPager) + assert response.page_size == 951 + assert response.next_page_token == 'next_page_token_value' + + +def test_list_reference_images_rest_required_fields(request_type=product_search_service.ListReferenceImagesRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_reference_images._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_reference_images._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_reference_images(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_reference_images_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_reference_images._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_reference_images_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_reference_images") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_reference_images") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListReferenceImagesRequest.pb(product_search_service.ListReferenceImagesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListReferenceImagesResponse.to_json(product_search_service.ListReferenceImagesResponse()) + + request = product_search_service.ListReferenceImagesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListReferenceImagesResponse() + + client.list_reference_images(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_reference_images_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListReferenceImagesRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_reference_images(request) + + +def test_list_reference_images_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListReferenceImagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListReferenceImagesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_reference_images(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{parent=projects/*/locations/*/products/*}/referenceImages" % client.transport._host, args[1]) + + +def test_list_reference_images_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_reference_images( + product_search_service.ListReferenceImagesRequest(), + parent='parent_value', + ) + + +def test_list_reference_images_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + next_page_token='abc', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[], + next_page_token='def', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + ], + next_page_token='ghi', + ), + product_search_service.ListReferenceImagesResponse( + reference_images=[ + product_search_service.ReferenceImage(), + product_search_service.ReferenceImage(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListReferenceImagesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'parent': 'projects/sample1/locations/sample2/products/sample3'} + + pager = client.list_reference_images(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.ReferenceImage) + for i in results) + + pages = list(client.list_reference_images(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.GetReferenceImageRequest, + dict, +]) +def test_get_reference_image_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage( + name='name_value', + uri='uri_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_reference_image(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, product_search_service.ReferenceImage) + assert response.name == 'name_value' + assert response.uri == 'uri_value' + + +def test_get_reference_image_rest_required_fields(request_type=product_search_service.GetReferenceImageRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_reference_image._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_reference_image(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_reference_image_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_reference_image._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_reference_image_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_get_reference_image") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_get_reference_image") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.GetReferenceImageRequest.pb(product_search_service.GetReferenceImageRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ReferenceImage.to_json(product_search_service.ReferenceImage()) + + request = product_search_service.GetReferenceImageRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ReferenceImage() + + client.get_reference_image(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_reference_image_rest_bad_request(transport: str = 'rest', request_type=product_search_service.GetReferenceImageRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_reference_image(request) + + +def test_get_reference_image_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ReferenceImage() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/products/sample3/referenceImages/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ReferenceImage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_reference_image(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/products/*/referenceImages/*}" % client.transport._host, args[1]) + + +def test_get_reference_image_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_reference_image( + product_search_service.GetReferenceImageRequest(), + name='name_value', + ) + + +def test_get_reference_image_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.AddProductToProductSetRequest, + dict, +]) +def test_add_product_to_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_product_to_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_add_product_to_product_set_rest_required_fields(request_type=product_search_service.AddProductToProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request_init["product"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_product_to_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_product_to_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_product_to_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_product_to_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_product_to_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_product_to_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_add_product_to_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.AddProductToProductSetRequest.pb(product_search_service.AddProductToProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.AddProductToProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.add_product_to_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_add_product_to_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.AddProductToProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.add_product_to_product_set(request) + + +def test_add_product_to_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + product='product_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_product_to_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/productSets/*}:addProduct" % client.transport._host, args[1]) + + +def test_add_product_to_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.add_product_to_product_set( + product_search_service.AddProductToProductSetRequest(), + name='name_value', + product='product_value', + ) + + +def test_add_product_to_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.RemoveProductFromProductSetRequest, + dict, +]) +def test_remove_product_from_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_product_from_product_set(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_remove_product_from_product_set_rest_required_fields(request_type=product_search_service.RemoveProductFromProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request_init["product"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_product_from_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_product_from_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_product_from_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_product_from_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_product_from_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", "product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_product_from_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_remove_product_from_product_set") as pre: + pre.assert_not_called() + pb_message = product_search_service.RemoveProductFromProductSetRequest.pb(product_search_service.RemoveProductFromProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = product_search_service.RemoveProductFromProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.remove_product_from_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_remove_product_from_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.RemoveProductFromProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.remove_product_from_product_set(request) + + +def test_remove_product_from_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + product='product_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = '' + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_product_from_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/productSets/*}:removeProduct" % client.transport._host, args[1]) + + +def test_remove_product_from_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.remove_product_from_product_set( + product_search_service.RemoveProductFromProductSetRequest(), + name='name_value', + product='product_value', + ) + + +def test_remove_product_from_product_set_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ListProductsInProductSetRequest, + dict, +]) +def test_list_products_in_product_set_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_products_in_product_set(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListProductsInProductSetPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_products_in_product_set_rest_required_fields(request_type=product_search_service.ListProductsInProductSetRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products_in_product_set._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_products_in_product_set._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("page_size", "page_token", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_products_in_product_set(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_products_in_product_set_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products_in_product_set._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_in_product_set_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_list_products_in_product_set") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_list_products_in_product_set") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ListProductsInProductSetRequest.pb(product_search_service.ListProductsInProductSetRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = product_search_service.ListProductsInProductSetResponse.to_json(product_search_service.ListProductsInProductSetResponse()) + + request = product_search_service.ListProductsInProductSetRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_search_service.ListProductsInProductSetResponse() + + client.list_products_in_product_set(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_products_in_product_set_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ListProductsInProductSetRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_products_in_product_set(request) + + +def test_list_products_in_product_set_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = product_search_service.ListProductsInProductSetResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = product_search_service.ListProductsInProductSetResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_products_in_product_set(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{name=projects/*/locations/*/productSets/*}/products" % client.transport._host, args[1]) + + +def test_list_products_in_product_set_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_products_in_product_set( + product_search_service.ListProductsInProductSetRequest(), + name='name_value', + ) + + +def test_list_products_in_product_set_rest_pager(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + #with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + product_search_service.Product(), + ], + next_page_token='abc', + ), + product_search_service.ListProductsInProductSetResponse( + products=[], + next_page_token='def', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + ], + next_page_token='ghi', + ), + product_search_service.ListProductsInProductSetResponse( + products=[ + product_search_service.Product(), + product_search_service.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_search_service.ListProductsInProductSetResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'name': 'projects/sample1/locations/sample2/productSets/sample3'} + + pager = client.list_products_in_product_set(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product_search_service.Product) + for i in results) + + pages = list(client.list_products_in_product_set(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize("request_type", [ + product_search_service.ImportProductSetsRequest, + dict, +]) +def test_import_product_sets_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.import_product_sets(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_product_sets_rest_required_fields(request_type=product_search_service.ImportProductSetsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).import_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).import_product_sets._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.import_product_sets(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_product_sets_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_product_sets._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_product_sets_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_import_product_sets") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_import_product_sets") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.ImportProductSetsRequest.pb(product_search_service.ImportProductSetsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = product_search_service.ImportProductSetsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_product_sets(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_product_sets_rest_bad_request(transport: str = 'rest', request_type=product_search_service.ImportProductSetsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.import_product_sets(request) + + +def test_import_product_sets_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.import_product_sets(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{parent=projects/*/locations/*}/productSets:import" % client.transport._host, args[1]) + + +def test_import_product_sets_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.import_product_sets( + product_search_service.ImportProductSetsRequest(), + parent='parent_value', + input_config=product_search_service.ImportProductSetsInputConfig(gcs_source=product_search_service.ImportProductSetsGcsSource(csv_file_uri='csv_file_uri_value')), + ) + + +def test_import_product_sets_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_search_service.PurgeProductsRequest, + dict, +]) +def test_purge_products_rest(request_type): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.purge_products(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_purge_products_rest_required_fields(request_type=product_search_service.PurgeProductsRequest): + transport_class = transports.ProductSearchRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).purge_products._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = 'parent_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).purge_products._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.purge_products(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_purge_products_rest_unset_required_fields(): + transport = transports.ProductSearchRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.purge_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_purge_products_rest_interceptors(null_interceptor): + transport = transports.ProductSearchRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductSearchRestInterceptor(), + ) + client = ProductSearchClient(transport=transport) + with mock.patch.object(type(client.transport._session), "request") as req, \ + mock.patch.object(path_template, "transcode") as transcode, \ + mock.patch.object(operation.Operation, "_set_result_from_operation"), \ + mock.patch.object(transports.ProductSearchRestInterceptor, "post_purge_products") as post, \ + mock.patch.object(transports.ProductSearchRestInterceptor, "pre_purge_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_search_service.PurgeProductsRequest.pb(product_search_service.PurgeProductsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(operations_pb2.Operation()) + + request = product_search_service.PurgeProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.purge_products(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_purge_products_rest_bad_request(transport: str = 'rest', request_type=product_search_service.PurgeProductsRequest): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, 'request') as req, pytest.raises(core_exceptions.BadRequest): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.purge_products(request) + + +def test_purge_products_rest_flattened(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name='operations/spam') + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.purge_products(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1p4beta1/{parent=projects/*/locations/*}/products:purge" % client.transport._host, args[1]) + + +def test_purge_products_rest_flattened_error(transport: str = 'rest'): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.purge_products( + product_search_service.PurgeProductsRequest(), + parent='parent_value', + ) + + +def test_purge_products_rest_error(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductSearchClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProductSearchClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductSearchGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProductSearchGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + transports.ProductSearchRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "rest", +]) +def test_transport_kind(transport_name): + transport = ProductSearchClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ProductSearchGrpcTransport, + ) + +def test_product_search_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ProductSearchTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_product_search_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.vision_v1p4beta1.services.product_search.transports.ProductSearchTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ProductSearchTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_product_set', + 'list_product_sets', + 'get_product_set', + 'update_product_set', + 'delete_product_set', + 'create_product', + 'list_products', + 'get_product', + 'update_product', + 'delete_product', + 'create_reference_image', + 'delete_reference_image', + 'list_reference_images', + 'get_reference_image', + 'add_product_to_product_set', + 'remove_product_from_product_set', + 'list_products_in_product_set', + 'import_product_sets', + 'purge_products', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_product_search_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('google.cloud.vision_v1p4beta1.services.product_search.transports.ProductSearchTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductSearchTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id="octopus", + ) + + +def test_product_search_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('google.cloud.vision_v1p4beta1.services.product_search.transports.ProductSearchTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductSearchTransport() + adc.assert_called_once() + + +def test_product_search_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ProductSearchClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + ], +) +def test_product_search_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( 'https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/cloud-vision',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductSearchGrpcTransport, + transports.ProductSearchGrpcAsyncIOTransport, + transports.ProductSearchRestTransport, + ], +) +def test_product_search_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ProductSearchGrpcTransport, grpc_helpers), + (transports.ProductSearchGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_product_search_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "vision.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/cloud-vision', +), + scopes=["1", "2"], + default_host="vision.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_product_search_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel") as mock_configure_mtls_channel: + transports.ProductSearchRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_product_search_rest_lro_client(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_search_host_no_port(transport_name): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_search_host_with_port(transport_name): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='vision.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'vision.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://vision.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_product_search_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ProductSearchClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ProductSearchClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_product_set._session + session2 = client2.transport.create_product_set._session + assert session1 != session2 + session1 = client1.transport.list_product_sets._session + session2 = client2.transport.list_product_sets._session + assert session1 != session2 + session1 = client1.transport.get_product_set._session + session2 = client2.transport.get_product_set._session + assert session1 != session2 + session1 = client1.transport.update_product_set._session + session2 = client2.transport.update_product_set._session + assert session1 != session2 + session1 = client1.transport.delete_product_set._session + session2 = client2.transport.delete_product_set._session + assert session1 != session2 + session1 = client1.transport.create_product._session + session2 = client2.transport.create_product._session + assert session1 != session2 + session1 = client1.transport.list_products._session + session2 = client2.transport.list_products._session + assert session1 != session2 + session1 = client1.transport.get_product._session + session2 = client2.transport.get_product._session + assert session1 != session2 + session1 = client1.transport.update_product._session + session2 = client2.transport.update_product._session + assert session1 != session2 + session1 = client1.transport.delete_product._session + session2 = client2.transport.delete_product._session + assert session1 != session2 + session1 = client1.transport.create_reference_image._session + session2 = client2.transport.create_reference_image._session + assert session1 != session2 + session1 = client1.transport.delete_reference_image._session + session2 = client2.transport.delete_reference_image._session + assert session1 != session2 + session1 = client1.transport.list_reference_images._session + session2 = client2.transport.list_reference_images._session + assert session1 != session2 + session1 = client1.transport.get_reference_image._session + session2 = client2.transport.get_reference_image._session + assert session1 != session2 + session1 = client1.transport.add_product_to_product_set._session + session2 = client2.transport.add_product_to_product_set._session + assert session1 != session2 + session1 = client1.transport.remove_product_from_product_set._session + session2 = client2.transport.remove_product_from_product_set._session + assert session1 != session2 + session1 = client1.transport.list_products_in_product_set._session + session2 = client2.transport.list_products_in_product_set._session + assert session1 != session2 + session1 = client1.transport.import_product_sets._session + session2 = client2.transport.import_product_sets._session + assert session1 != session2 + session1 = client1.transport.purge_products._session + session2 = client2.transport.purge_products._session + assert session1 != session2 +def test_product_search_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductSearchGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_product_search_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductSearchGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.ProductSearchGrpcTransport, transports.ProductSearchGrpcAsyncIOTransport]) +def test_product_search_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_product_search_grpc_lro_client(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_search_grpc_lro_async_client(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc_asyncio', + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_product_path(): + project = "squid" + location = "clam" + product = "whelk" + expected = "projects/{project}/locations/{location}/products/{product}".format(project=project, location=location, product=product, ) + actual = ProductSearchClient.product_path(project, location, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "octopus", + "location": "oyster", + "product": "nudibranch", + } + path = ProductSearchClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_product_path(path) + assert expected == actual + +def test_product_set_path(): + project = "cuttlefish" + location = "mussel" + product_set = "winkle" + expected = "projects/{project}/locations/{location}/productSets/{product_set}".format(project=project, location=location, product_set=product_set, ) + actual = ProductSearchClient.product_set_path(project, location, product_set) + assert expected == actual + + +def test_parse_product_set_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "product_set": "abalone", + } + path = ProductSearchClient.product_set_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_product_set_path(path) + assert expected == actual + +def test_reference_image_path(): + project = "squid" + location = "clam" + product = "whelk" + reference_image = "octopus" + expected = "projects/{project}/locations/{location}/products/{product}/referenceImages/{reference_image}".format(project=project, location=location, product=product, reference_image=reference_image, ) + actual = ProductSearchClient.reference_image_path(project, location, product, reference_image) + assert expected == actual + + +def test_parse_reference_image_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "product": "cuttlefish", + "reference_image": "mussel", + } + path = ProductSearchClient.reference_image_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_reference_image_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "winkle" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ProductSearchClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nautilus", + } + path = ProductSearchClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "scallop" + expected = "folders/{folder}".format(folder=folder, ) + actual = ProductSearchClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "abalone", + } + path = ProductSearchClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "squid" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ProductSearchClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "clam", + } + path = ProductSearchClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "whelk" + expected = "projects/{project}".format(project=project, ) + actual = ProductSearchClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "octopus", + } + path = ProductSearchClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "oyster" + location = "nudibranch" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ProductSearchClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + } + path = ProductSearchClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ProductSearchClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ProductSearchTransport, '_prep_wrapped_messages') as prep: + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ProductSearchTransport, '_prep_wrapped_messages') as prep: + transport_class = ProductSearchClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ProductSearchAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + with mock.patch.object(type(getattr(client.transport, "grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + with mock.patch.object(type(getattr(client.transport, close_name)), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = ProductSearchClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (ProductSearchClient, transports.ProductSearchGrpcTransport), + (ProductSearchAsyncClient, transports.ProductSearchGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + )